ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从 Handsontable 8.4 迁移到 9.0:HyperFormula 公式引擎升级与 API 破坏性变更实战指南

从 Handsontable 8.4 迁移到 9.0:HyperFormula 公式引擎升级与 API 破坏性变更实战指南 前端UI组件【免费下载链接】handsontableJavaScript Data Grid / Data Table with a Spreadsheet Look Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡项目地址https://gitcode.com/gh_mirrors/ha/handsontable点击查看免费下载本篇指南面向所有正在使用 Handsontable 8.4.x、计划升级到 9.0.02021 年 6 月 1 日发布的开发者。9.0 版本用全新的 HyperFormula 公式引擎彻底替换了旧引擎公式插件的初始化方式、公开方法、Autofill 钩子签名均发生了破坏性变更同时移除了 Header Tooltips 与 Observe Changes 两个已废弃插件。读完本文你将掌握从 8.4 到 9.0 的完整迁移路径如何传入 HyperFormula 依赖、如何逐个替换旧的公式 API 调用、如何适配新的beforeAutofill/afterAutofill签名以及如何用官方钩子复刻被移除插件的功能。升级背景与总体影响Handsontable 9.0.0 的核心变化是引入了一个全新的公式引擎基于 HyperFormula 实现完全取代旧版本内置的公式计算引擎。这意味着两件事公式插件的初始化方式变了旧版只需formulas: true即可开启新版必须显式传入 HyperFormula 引擎。公式 API 发生了破坏性变更旧插件公开的一系列方法如getCellValue、setVariable、recalculate等在新版中要么被更强大的替代方案取代要么被直接移除。升级前建议先阅读 9.0.0 的发布博客与完整变更日志并对照本文逐一排查代码中的公式插件用法。整个迁移可以分为四个层面插件初始化、公式方法调用、Autofill 钩子签名、以及被移除插件的替代方案。插件初始化方式从formulas: true到传入 HyperFormula9.0 中最直观的破坏性变更在于插件初始化。旧版用布尔值开启公式功能新版则要求你把 HyperFormula 作为外部依赖传入插件配置。JavaScript 用法对比9.0 之前旧版插件9.0 之后新版插件formulas: trueimport { HyperFormula } from hyperformula;formulas: {engine: HyperFormula}React 用法对比9.0 之前旧版插件9.0 之后新版插件formulas{true}import { HyperFormula } from hyperformula;formulas{{engine: HyperFormula}}Vue 与 Angular 的写法同理核心都是把formulas配置从布尔值改为包含engine键的对象。源码视角引擎是如何被接进来的从 register.ts 的setupEngine实现可以看出插件对engine字段的解析非常灵活支持三种形态HyperFormula 类Class插件内部调用engineClass.buildEmpty(engineSettings)自动创建引擎实例HyperFormula 实例Instance直接复用外部创建好的引擎实例并通过全局注册表记录该实例与 Handsontable 实例的关联关系{ hyperformula: HyperFormulaClass }包装对象兼容从engine.hyperformula键取值的形式。此外插件在创建引擎时还会应用一套默认设置见 settings.ts 中的DEFAULT_SETTINGS包括useArrayArithmetic: true、evaluateNullToZero: true、precisionRounding: 14、smartRounding: true、nullDate1899-12-30等这些默认值保证了 HyperFormula 与 Handsontable 的日期、数值语义对齐。注意其中leapYear1900与nullDate默认值不应被改动——register.ts 会检测用户是否修改了这两个设置若不一致会发出警告因为改动它们会导致两个库的日期无法正确同步。更多初始化方法除了传入引擎类之外新版插件还支持“多个独立 Handsontable 实例各自带引擎”“多个实例共享同一个 HyperFormula 实例”“外部共享引擎实例”等更高级的初始化模式详见公式计算指南中的「Initialization methods」一节。共享引擎场景下register.ts 会通过engine_relationship与shared_engine_usage两个全局注册表维护引擎与实例的对应关系这也是后面destroy()语义变化的根源。公式方法迁移对照表9.0 中公式插件公开的方法集合发生了显著变化。下表逐项对照旧版方法与新版替代方案方法名9.0 之前旧版插件9.0 之后新版插件destroyhot.getPlugin(formulas).destroy()保持不变。但该方法只会在 HyperFormula 实例与所有 Handsontable 实例断开连接后才真正销毁该实例。disablePluginhot.getPlugin(formulas).disablePlugin()保持不变。enablePluginhot.getPlugin(formulas).enablePlugin()保持不变但注意如果你没有通过updateSettings或 Handsontable 初始化时传入插件配置此方法将不会产生任何效果。getCellValuehot.getPlugin(formulas).getCellValue(row, column)改用基础 Handsontable API例如hot.getDataAtCell(row, column)。getVariablehot.getPlugin(formulas).getVariable(variableName)旧版“变量”被更强大的替代方案取代命名表达式named expressions。hasComputedCellValuehot.getPlugin(formulas).hasComputedCellValue(row, column)hot.getPlugin(formulas).getCellType(row, column) FORMULAisEnabledhot.getPlugin(formulas).isEnabled()保持不变。recalculatehot.getPlugin(formulas).recalculate()hot.getPlugin(formulas).engine.rebuildAndRecalculate()recalculateFullhot.getPlugin(formulas).recalculateFull()hot.getPlugin(formulas).engine.rebuildAndRecalculate()recalculateOptimizedhot.getPlugin(formulas).recalculateOptimized()hot.getPlugin(formulas).engine.rebuildAndRecalculate()setVariablehot.getPlugin(formulas).setVariable(variableName, value)旧版“变量”被更强大的替代方案取代命名表达式。关键迁移点解读getCellValue→ 基础 API。旧版需要穿透插件层读取计算后的单元格值新版中这些值已经通过插件与 Handsontable 的数据同步机制写回表格因此直接用hot.getDataAtCell(row, column)即可代码更简洁。getVariable/setVariable→ 命名表达式。命名表达式是 HyperFormula 提供的更强大机制可以在初始化时通过插件配置传入见下文也可以在运行时由引擎动态添加。相关用法可参考公式计算指南中的「Named expressions」一节其中包含纯值命名表达式与基于公式的命名表达式两类完整示例。hasComputedCellValue→getCellType判断。新版插件保留了getCellType(row, column, sheet?)方法源码见 formulas.ts返回引擎判定出的单元格类型。单元测试formulas.spec.js验证了它可能返回FORMULA、VALUE、ARRAYFORMULA、EMPTY等取值因此“是否已计算出公式值”等价于“单元格类型是否为FORMULA”。三个recalculate*方法统一为engine.rebuildAndRecalculate()。新版插件不再区分全量重算与优化重算直接调用底层引擎的重建与重算方法即可。注意新版把引擎实例暴露在hot.getPlugin(formulas).engine属性上这是访问 HyperFormula 全部能力的入口。destroy()语义变化。因为现在多个 Handsontable 实例可能共享同一个 HyperFormula 引擎见前文注册表机制destroy()不再简单销毁实例而是先解除当前表格与引擎的关联只有当引擎不再关联任何 Handsontable 实例时才会真正销毁。命名表达式的配置入口命名表达式可以在初始化时作为插件配置传入register.ts 中的registerEngine会调用registerNamedExpressions(engineInstance, pluginSettings.namedExpressions)注册它们。插件配置对象因此扩展为new Handsontable(container, { formulas: { engine: HyperFormula, // 可选命名表达式 namedExpressions: [ { name: MY_VAR, expression: 42 }, { name: DOUBLE, expression: MY_VAR * 2 } ], // 可选自定义函数、公式语言等 functions: [...], language: { langCode: enGB } } });其中language配置会被 settings.ts 中的getEngineSettingsOverrides提取为引擎的language设置实现公式函数语言如enGB、plPL的切换。可用公式函数新版插件本身不再内置公式函数清单——公式函数全部由 HyperFormula 引擎提供。完整的可用函数列表位于 HyperFormula 仓库的src/interpreter/plugin目录下涵盖数学、统计、逻辑、文本、日期时间、查找引用、财务等各类函数。除此之外插件还允许通过formulas.functions配置注册自定义函数引擎在初始化时会调用registerCustomFunctions将其挂载到引擎上见 register.ts。Autofill 钩子签名变更更强大的填充控制为了让 Autofill拖拽填充钩子更一致、更强大9.0 中beforeAutofill与afterAutofill采用了全新的签名。变更前8.4 及之前new Handsontable(container, { data, beforeAutofill(start, end, data) {}, afterAutofill(start, end, data) {} })变更后9.0 起new Handsontable(container, { data, beforeAutofill(selectionData, sourceRange, targetRange, direction) { const start targetRange.from; // 旧版参数 start const end targetRange.to; // 旧版参数 end const data selectionData; // 旧版参数 data }, afterAutofill(fillData, sourceRange, targetRange, direction) { const start targetRange.from; // 旧版参数 start const end targetRange.to; // 旧版参数 end const data fillData; // 旧版参数 data } })React 中的对应写法HotTable data{data} beforeAutofill{(selectionData, sourceRange, targetRange, direction) { const start targetRange.from; // 旧版参数 start const end targetRange.to; // 旧版参数 end }} afterAutofill{(fillData, sourceRange, targetRange, direction) { const start targetRange.from; // 旧版参数 start const end targetRange.to; // 旧版参数 end }} /新参数的含义selectionData/fillData被填充的数据二维数组分别对应旧版的data参数sourceRange填充源选区CellRange对象targetRange填充目标选区CellRange对象旧版的start/end可以从targetRange.from/targetRange.to获取direction拖拽方向up、down、left、right之一。用返回值取代直接修改data最重要的行为变化在于beforeAutofill不再通过修改data参数来定制填充内容而是直接返回一个新的二维数组作为填充模式。从 autofill.ts 的实现可以看到插件以(selectionData, sourceRange, targetRange, directionOfDrag)四个参数触发钩子并读取返回值返回false取消本次填充源码中会清除填充高亮并重新渲染返回新数组该数组即为填充数据插件随后会按拖拽方向#adjustFillDataForDirection和源数据扩展#applySourceDataExtension调整它再写入目标区域返回undefined使用默认填充行为。而afterAutofill则在填充数据写入完成、选区设置之后以(fillData, sourceRange, targetRange, directionOfDrag)触发见 autofill.ts 中runHooks(afterAutofill, ...)的调用位置。该插件配套的钩子测试见 beforeAutofill.spec.js 与 afterAutofill.spec.js升级后建议同步更新这些测试断言。被移除的插件与替代方案9.0.0 移除了两个此前已废弃的插件Header Tooltips表头提示Observe Changes变更观察Header Tooltips改用表头钩子要实现与 Header Tooltips 类似的功能鼠标悬停表头时显示标题提示可以借助afterGetColHeader与afterGetRowHeader钩子在表头单元格TH元素上设置title属性。完整示例const onAfterGetHeader function(index, TH) { TH.setAttribute(title, TH.querySelector(span).textContent); }; const example document.querySelector(#tooltip-example); const hot new Handsontable(example, { data: [ [A1, B1, C1], [A2, B2, C2], [A3, B3, C3], ], rowHeights: 23, autoColumnSize: true, rowHeaders: [1st, 2nd, 3rd], colHeaders: [First Column, Second Column, Third Column], licenseKey: non-commercial-and-evaluation, afterGetColHeader: onAfterGetHeader, afterGetRowHeader: onAfterGetHeader });React 中的等价实现const onAfterGetHeader function(index, TH) { TH.setAttribute(title, TH.querySelector(span).textContent); }; HotTable data{[ [A1, B1, C1], [A2, B2, C2], [A3, B3, C3], ]} rowHeights{23} autoColumnSize{true} rowHeaders{[1st, 2nd, 3rd]} colHeaders{[First Column, Second Column, Third Column]} licenseKeynon-commercial-and-evaluation afterGetColHeader{onAfterGetHeader} afterGetRowHeader{onAfterGetHeader} /这段实现之所以可行是因为afterGetColHeader/afterGetRowHeader钩子会为每一列/每一行的表头提供(index, TH)参数TH.querySelector(span)可拿到表头文本节点。升级后只要把原来的插件开启配置删掉、替换为上述钩子即可。Observe Changes停止监听相关钩子Observe Changes 插件此前会触发afterChangesObserved钩子。升级到 9.0.0含以上版本后请务必删除对该钩子的监听否则相关回调将永远不会被调用。同时如果代码中仍有observeChanges: true之类的配置也需要一并移除。升级后的验证清单完成以上所有改动后你的应用即运行在 Handsontable 9.0 之上。建议按以下清单做最终验证依赖确认项目已安装hyperformula依赖且formulas配置为{ engine: HyperFormula }形式公式功能创建包含公式的表格验证计算、跨单元格引用、数组公式ARRAYFORMULA均正常可参考公式计算指南中的完整示例API 调用全局搜索getPlugin(formulas)逐一核对是否仍在使用旧版方法getCellValue、getVariable、setVariable、recalculate*等并按上表替换Autofill检查所有beforeAutofill/afterAutofill回调确认已适配新签名且beforeAutofill不再直接修改data参数废弃插件移除 Header Tooltips、Observe Changes 相关配置与钩子监听必要时用表头钩子方案替代测试更新公式插件formulas.spec.js与 Autofill 钩子测试beforeAutofill.spec.js、afterAutofill.spec.js中的断言确保新行为被覆盖。迁移完成。如果你在升级过程中遇到公式引擎相关的疑难问题可以回到 formulas 插件源码 与引擎注册/设置模块追踪具体实现并结合升级与迁移指南与公式计算指南定位解决方案。赞分享前端UI组件【免费下载链接】handsontableJavaScript Data Grid / Data Table with a Spreadsheet Look Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡项目地址https://gitcode.com/gh_mirrors/ha/handsontable点击查看免费下载相关推荐Handsontable 从 8.4 迁移到 9.0 版本指南Handsontable 从 8.4 迁移到 9.0 版本指南 概述 Handsontable 9.0 版本于 2021 年 6 月 1 日发布带来了革命性的前端UI组件Handsontable 9.0 升级到 10.0 迁移指南钩子重命名、HyperFormula 升级与默认值变更全解析Handsontable 9.0 升级到 10.0 迁移指南钩子重命名、HyperFormula 升级与默认值变更全解析 Handsontable 10.0.前端UI组件3步掌握GenankiPython自动化创建Anki卡片的终极指南3步掌握GenankiPython自动化创建Anki卡片的终极指南 还在为手动制作Anki卡片而烦恼吗Genanki这个强大的Python库将彻底改变你的学教育上一篇TigerVNC高DPI显示适配Surface类的缩放因子与字体渲染优化下一篇Swagger Editor国际化支持多语言环境配置指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表