唯杰地图 logo唯杰地图
VJMAP
EN

document-events

vjcad/references/event/document-events.md 6.1 KB119 行
原文

本文回答:CadEvents 枚举里有 10 个基础文档事件 DocumentCreating/Created/Opening/Opened/Closing/Closed/Saving/Saved/Modified/Switched,外加协作类(DocumentUploading/Uploaded/Downloading/Downloaded/SyncStatusChanged)和缓存类(DocumentCaching/Cached/Restoring/Restored/CacheCleared)。当前版本真正派发的只有 DocumentCreating/Created/Modified/Switched;DocumentOpening/Opened/Closing/Closed/Saving/Saved 及协作、缓存、分支、Patch、冲突类事件没有任何派发点(订阅永不触发)。阻止保存/关闭请在命令层用 CommandStarting 拦截 QSAVE/SAVEAS/SAVESERVER/SAVELOCAL/CLOSE;"打开/保存之后"用 CommandEnded。

一、基础事件清单

事件 说明 可取消 当前版本
DocumentCreating 新建前(Engine.docs.add();打开文件时也会先建空文档) 是 ✓ 派发
DocumentCreated 新建后(打开文件时此刻内容尚未载入) 否 ✓ 派发
DocumentOpening 打开前 是 ✗ 未派发
DocumentOpened 打开后 否 ✗ 未派发
DocumentClosing 关闭前 是 ✗ 未派发
DocumentClosed 关闭后 否 ✗ 未派发
DocumentSaving 保存前 是 ✗ 未派发
DocumentSaved 保存后 否 ✗ 未派发
DocumentModified 文档从"未修改"变为"已修改"(DBMOD 0→1)时触发一次 否 ✓ 派发
DocumentSwitched 切换活动文档后(args {previousDocument, currentDocument}) 否 ✓ 派发

MCP 参考:vjcad/doc/event/event-types.md(清单);派发点以发布包中实际 emit(CadEvents.*) 为准。

二、最小用法

Engine.eventManager.on(CadEvents.DocumentCreated, (args) => {
  console.log('新文档:', args.document.name);   // 打开文件时内容此刻尚未载入
});

Engine.eventManager.on(CadEvents.DocumentSwitched, (args) => {
  console.log('切换到:', args.currentDocument.name);
});

// "打开 / 保存之后":DocumentOpened / DocumentSaved 不派发,改看命令结束
// (用户取消也会触发 CommandEnded;success 只表示 main 没抛异常)
Engine.eventManager.on(CadEvents.CommandEnded, (args) => {
  if (['OPEN', 'OPENFROMSERVER', 'OPENFROMLOCAL'].includes(args.commandName)) console.log('打开命令结束');
  if (['QSAVE', 'SAVEAS', 'SAVESERVER', 'SAVELOCAL'].includes(args.commandName)) console.log('保存命令结束');
});

Engine.eventManager.on(CadEvents.DocumentModified, () => {
  scheduleAutoSave();   // 仅 clean→dirty 时触发一次
});

MCP 参考:vjcad/example/event/05documentevents.js、vjcad/doc/event/event-usage.md(官方示例里的 DocumentOpened/DocumentSaved 订阅在当前版本不会触发)。

三、阻止保存空文档

DocumentSaving 不派发,在命令启动前拦截:

Engine.eventManager.on(CadEvents.CommandStarting, (args) => {
  const saveCmds = ['QSAVE', 'SAVEAS', 'SAVESERVER', 'SAVELOCAL'];
  if (saveCmds.includes(args.commandName) && Engine.getEntities(e => e.isAlive).length === 0) {
    args.cancel = true;
    alert('文档为空,无法保存');
  }
});

四、关闭确认

DocumentClosing 不派发;内置 CLOSE 命令自己已对未保存文档(DBMOD === 1)弹确认框。要追加自定义检查,同样拦截命令(注意:文档标签上的 × 按钮走 DocumentTabs 自己的关闭逻辑,不经过 CLOSE 命令,拦不到):

Engine.eventManager.on(CadEvents.CommandStarting, (args) => {
  if (args.commandName === 'CLOSE' && !myBusinessCheckPassed()) {
    args.cancel = true;
    writeMessage('<br/>业务校验未通过,禁止关闭');
  }
});

MCP 参考:vjcad/doc/event/event-usage.md(原文用 DocumentClosing,当前版本不触发)。

五、协作 / 同步事件(✗ 均未派发)

事件 说明 可取消
DocumentUploading / DocumentUploaded 上传到服务端 是 / 否
DocumentDownloading / DocumentDownloaded 从服务端下载 是 / 否
DocumentSyncStatusChanged 同步状态变化 否

以上只存在于枚举,当前版本没有派发点;需要同步状态时在 SAVESERVER 等命令的 CommandEnded 里自行查询。

MCP 参考:vjcad/doc/event/event-types.md。

六、本地缓存事件(✗ 均未派发)

事件 说明 可取消
DocumentCaching / DocumentCached 保存到本地缓存 是 / 否
DocumentRestoring / DocumentRestored 从本地缓存恢复 是 / 否
DocumentCacheCleared 缓存清理后 否

MCP 参考:vjcad/doc/event/event-types.md。

七、分支 / Patch / 冲突事件(✗ 均未派发)

事件 说明
BranchCreating/Created/Switching/Switched/Merging/Merged/Deleting/Deleted 分支生命周期
PatchCreating/Created/Applying/Applied/Reverting/Reverted Patch 生命周期
ConflictDetected/Resolving/Resolved/Skipped 冲突

这组事件目前只是枚举占位,订阅不会触发;协作 UI 提示请基于版本 API 的返回值(见 version)。

MCP 参考:vjcad/doc/event/event-types.md、version。

反例

  • 订阅 DocumentSaving / DocumentOpened / DocumentClosing 等未派发事件,以为拦截/回调生效:永远不会触发。
  • 用 CommandStarting 拦截保存但不调用任何用户提示:用户以为没存上但其实是被静默阻止。
  • 在打开命令的 CommandEnded 里调耗时操作(5+ 秒):阻塞 UI,建议异步触发。
  • 拿 DocumentModified 统计"每次修改":它只在 clean→dirty 时触发一次,直到保存(或撤销回保存点)清除 DBMOD 前不再触发;缩放(setZoom/zoomIn/zoomOut)还会直接置 DBMOD=1 而不派发,之后的编辑也不再触发。逐次变更请监听 EntityModified / EntityAdded / EntitiesErased / UndoStackChanged。

参考(官方文档 MCP)

  • 文档:vjcad/doc/event/event-types.md、vjcad/doc/event/event-usage.md
  • 示例:vjcad/example/event/05documentevents.js