ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

OHIF 3.10 热键(Hotkeys)管理迁移指南:从 mode factory 到 customizationService

2026/9/18 20:14:20 拓冰建站 浏览量
OHIF 3.10 热键(Hotkeys)管理迁移指南:从 mode factory 到 customizationService OHIF 3.10 热键Hotkeys管理迁移指南从 mode factory 到 customizationService【免费下载链接】ViewersOHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages项目地址: https://gitcode.com/GitHub_Trending/vi/Viewers导读本文是 OHIF v3.9 升级到 v3.10 时热键Hotkeys系统迁移的完整技术指南。OHIF 在 3.10 中不再允许在 mode factory 中通过hotkeys: [...hotkeys.defaults.hotkeyBindings]声明快捷键而是统一交由customizationService下的ohif.hotkeyBindings键管理同时HotkeysManager在默认值处理、用户偏好持久化与生命周期清理上做了大量重构。读完本文你将掌握如何在 mode 中移除旧的热键数组、如何用$set/$push替换或追加自定义热键、为何window.config.hotkeys可以直接删除以及新版user-preferred-keys存储格式与自动迁移机制背后的源码实现。一、迁移背景与核心变化OHIF 3.10 对热键系统的改动是“去中心化、统一自定义”设计哲学的体现热键不再是一种特殊的 mode 配置而是与其他 UI 特性一样成为可以被 Customization Service 在运行时动态覆盖的普通“自定义项”。官方迁移文档hotkeys.md总结的关键变化如下热键不再定义在 mode factory 中旧写法hotkeys: [...hotkeys.defaults.hotkeyBindings]被废弃。热键由customizationService统一管理注册键为ohif.hotkeyBindings。默认热键自动生效系统会基于默认绑定自动初始化无需手动传入。用户偏好存储格式变更用户自定义的热键偏好改用 localStorage 中的新格式保存。HotkeysManager大版本更新默认值处理、按键持久化与清理逻辑均被显著增强。二、默认热键从哪来customization 模块注入在 3.10 中默认热键并不需要开发者手动提供而是由 default 扩展以 customization 模块的形式注入。对应源码位于 extensions/default/src/customizations/hotkeyBindingsCustomization.tsimport { defaults } from ohif/core; export default { ohif.hotkeyBindings: defaults.hotkeyBindings, };这里的defaults.hotkeyBindings即核心包导出的默认绑定数组定义在 platform/core/src/defaults/hotkeyBindings.ts并由 platform/core/src/defaults/index.js 统一导出。该文件包含约 40 条默认绑定覆盖工具切换、视口操作、浏览导航、窗宽窗位预设、标注编辑与分割笔刷等典型场景例如命令键位说明setToolActiveZoomz激活缩放工具scaleUpViewport放大视口fitViewportToWindow视口适配窗口rotateViewportCWr视口顺时针旋转invertViewporti图像反色incrementActiveViewportright切换到下一视口updateViewportDisplaySetdirection: 1pagedown切换到下一序列nextStagecontext:DEFAULT.下一阶段resetViewportspace重置视口setWindowLevelPresetct-soft-tissue 等1~4四个窗宽窗位预设undo/redoctrlz/ctrly撤销 / 重做increaseBrushSize/decreaseBrushSize]/[增大 / 减小笔刷每条默认绑定都遵循统一的Hotkey数据结构见 platform/core/src/classes/Hotkey.tscommandName要执行的命令、commandOptions命令参数用于区分同一命令的不同变体、context可选命令上下文、label展示名称、keys键位数组遵循 Mousetrap.js 语法、isEditable是否允许用户编辑。从源码结构看大部分绑定显式设置了isEditable: true而toggleCine、cancelActiveOperation、deleteActiveAnnotation等绑定未设置该字段——这并非疏漏而是依赖HotkeysManager.getValidDefinitions中的兜底逻辑当isEditable为undefined时会被统一改写为true。在应用启动流程中platform/app/src/routes/Mode/Mode.tsx 会在onModeEnter之后从 Customization Service 读取该键并交给hotkeysManagerconst hotkeys customizationService.getCustomization(ohif.hotkeyBindings); hotkeysManager.setDefaultHotKeys(hotkeys);由此可见默认热键的注入与读取完全走自定义系统管线这是 3.10 与旧版最本质的区别。三、迁移步骤一从 mode factory 中移除 hotkeys 数组3.9 及更早版本中mode 文件通常是这样写的- function modeFactory({ modeConfiguration }) { - return { - id: basic, - // ... other configuration - hotkeys: [...hotkeys.defaults.hotkeyBindings], - }; - }3.10 之后mode factory 中不再需要也不再支持hotkeys字段直接删除即可 function modeFactory({ modeConfiguration }) { return { id: basic, // ... other configuration // No hotkeys array necessary }; }由于默认绑定已经由 default 扩展的 customization 模块注入且Mode.tsx会在进入 mode 时自动读取ohif.hotkeyBindings并调用setDefaultHotKeys因此删除后默认热键依旧完整可用开发者无需做任何额外补偿。参考现有 mode 的实现modes/basic-test-mode/src/index.ts 与 modes/usAnnotation/src/index.ts 已不再声明hotkeys数组可以作为迁移后的范式样本。四、迁移步骤二用 Customization Service 定义自定义热键自定义热键的入口从 mode factory 转移到了onModeEnter中的customizationService.setCustomizations。Customization Service 基于 immutability-helper 语义提供多种命令操作符详见 platform/core/src/services/CustomizationService/CustomizationService.ts 与配套测试 CustomizationService.test.js。a. 用$set整体替换全部热键如果希望完全接管热键定义例如在专用 mode 中只保留少量快捷键使用$set整体替换ohif.hotkeyBindings onModeEnter: function ({ servicesManager }) { const { customizationService } servicesManager.services; customizationService.setCustomizations({ ohif.hotkeyBindings: { $set: [ { commandName: setToolActive, commandOptions: { toolName: Zoom }, label: Zoom, keys: [z], isEditable: true, }, ], }, });注意$set会完全替换整个绑定数组替换后系统只保留你列出的热键。默认绑定在替换后被覆盖因此如果只想做局部调整应优先使用$push。b. 用$push追加新的热键如果只想在默认绑定的基础上新增热键使用$push追加到数组末尾 onModeEnter: function ({ servicesManager }) { const { customizationService } servicesManager.services; customizationService.setCustomizations({ ohif.hotkeyBindings: { $push: [ { commandName: myCustomCommand, label: My Custom Function, keys: [ctrlm], isEditable: true, }, ], }, }); }$push对应 immutability-helper 的数组追加语义与$set、$unshift、$splice等操作符一样被 Customization Service 原生支持其行为在 CustomizationService.test.js 中有完整的测试覆盖。c. 修改既有热键的键位由于每个绑定以commandName commandOptions的哈希作为唯一标识见下文generateHash说明当$set中给出的绑定与默认绑定的哈希一致时会覆盖对应命令的键位而commandOptions不同则视为不同命令。因此如果要“改键”而非“加键”需要把被修改的命令连同新的keys通过$set完整写出同时保留其他默认绑定或结合$push与默认值合并使用。五、迁移步骤三window.config.hotkeys可以直接删除如果你的应用此前在window.config.js中配置了hotkeys字段- window.config { - // ...other config - hotkeys: [ - { - commandName: incrementActiveViewport, - label: Next Viewport, - keys: [right], - }, - // ...more hotkeys - ], - };迁移文档明确指出旧版window.config.hotkeys实际上从未真正生效。因此无需迁移逻辑直接安全移除即可 window.config { // ...other config };这一点从源码也可以印证3.10 的Mode.tsx热键初始化流程完全基于customizationService.getCustomization(ohif.hotkeyBindings)与window.config中的热键字段无关。六、用户偏好的新存储格式与自动迁移新格式user-preferred-keys3.10 中用户或应用代码自行修改过的热键会以哈希键值映射的形式持久化到 localStorage 的user-preferred-keys键下而不再是保存完整的绑定数组。哈希由HotkeysManager.generateHash生成HotkeysManager.ts本质是对{ commandName, commandOptions }做 object-hash 运算generateHash(definition) { return objectHash({ commandName: definition.commandName, commandOptions: definition.commandOptions || {}, }); }该哈希与 HotkeysManager.ts 中getValidHotkeyDefinitions用来构造定义索引的哈希一致因此默认绑定与用户偏好能够精确对齐到同一条命令。当用户偏好中存在某命令的哈希时setDefaultHotKeys会用userPreferredKeys[commandHash]覆盖默认keys后再注册见 HotkeysManager.ts而当热键被重新注册且哈希已存在时新键位也会被回写进user-preferred-keys见 HotkeysManager.ts。localStorage中的数据形态大致如下{ commandNamecommandOptions 的 object-hash: [ctrlm], 另一个命令的哈希: [space] }自动迁移工具migrateHotkeys.ts为了兼容 3.9 遗留的本地存储核心包提供了自动迁移工具 platform/core/src/utils/hotkeys/migrateHotkeys.tsHotkeysManager构造函数中会立即调用它见 HotkeysManager.ts。其逻辑要点读取旧键hotkey-definitions旧版完整绑定数组与标记位hotkeys-migrated若不存在旧数据或已迁移过直接返回遍历旧定义只有当旧绑定与默认绑定不一致命令哈希相同但keys不同或命令哈希在默认绑定中不存在时才将其写入user-preferred-keys最后写入hotkeys-migrated true并清除hotkey-definitions整个迁移过程被 try/catch 包裹失败时置hotkeys-migrated false保证下次可重试。因此绝大多数使用者无需手工处理迁移但如果你有代码直接读取 localStorage 中的热键数据请务必改用新格式。该迁移标记hotkeys-migrated在 3.12 的 escape-cancel-hotkey 迁移文档 中也被继续沿用说明这套格式已成为后续版本的基础设施。七、HotkeysManager 的关键实现与生命周期注册与去重registerHotkeysHotkeysManager.ts负责把热键定义交给底层 Mousetrap 绑定若commandName缺失直接抛错若同一哈希的绑定已存在且keys完全相同则跳过重复注册若已存在但keys变化先把新键位写入user-preferred-keys再解绑旧键、绑定新键。绑定与执行_bindHotkeysHotkeysManager.ts将keys数组用连接成 Mousetrap 语法例如[ctrl,m]→ctrlm绑定回调中依次执行preventDefault、stopPropagation通过_commandsManager.runCommand(commandName, { evt, ...commandOptions }, context)执行命令并广播HOTKEY_PRESSED事件event::hotkeysManager:hotkeyPressed便于其他模块订阅热键触发行为。清理与默认值恢复restoreDefaultBindings使用构造时保存的默认绑定一键还原destroy清空hotkeyDefaults与hotkeyDefinitions并调用 Mousetrap 的resetMode 退出时由 Mode.tsx 调用避免跨 mode 残留绑定disable/enable通过 Mousetrap 的pause/unpause实现全局热键开关例如弹出模态框时禁用热键。错误兜底setHotkeys捕获注册过程中的异常并通过uiNotificationService弹出错误提示避免热键配置错误导致应用静默失败见 HotkeysManager.ts。八、本次改动的收益API 一致热键与工具栏、面板、右键菜单等一样统一走 Customization Service 模式学习与维护成本下降。更灵活$set/$push/$unshift/$splice等操作符让“只改一条快捷键”成为可能无需整体替换。用户偏好更健壮哈希映射格式配合自动迁移工具用户自定义键位在不同版本间能更好地保留与升级。支持运行时更新热键可在 mode 运行期间通过setCustomizations动态增删改无需重启应用。生命周期更干净destroy Mousetrapreset的清理机制避免 mode 切换时的键位污染默认值恢复能力也更强。结语热键迁移是 OHIF 3.9 → 3.10 中“自定义系统统一化”的典型样本开发者只需要理解ohif.hotkeyBindings这一个注册键配合$set/$push两种操作符即可完成绝大多数迁移工作。迁移完成后建议通过查看 hotkeyBindingsCustomization.ts 理解默认注入参考 HotkeysManager.ts 理解注册、持久化与清理细节并在 CustomizationService.test.js 中验证各类操作符的行为确保自定义热键在新架构下稳定可靠。【免费下载链接】ViewersOHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages项目地址: https://gitcode.com/GitHub_Trending/vi/Viewers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考