唯杰地图 logo唯杰地图
VJMAP
EN

bus-render-store

vjmapext/references/event/bus-render-store.md 3.7 KB81 行
原文

本文回答:渲染 / 存储事件 —— render:requested / store:changed(⚠️ 1.0.1 枚举有定义但从未发射)+ 真实可用的 undo:performed / redo:performed。

一、事件列表

常量 字符串 payload 状态
RenderRequested render:requested — ⚠️ 1.0.1 bundle 中无任何 emit 点(订阅永远收不到)
StoreChanged store:changed — ⚠️ 同上,死枚举
—(非枚举) undo:performed 无 payload ✅ undoManager.undo() 完成后发射
—(非枚举) redo:performed 无 payload ✅ undoManager.redo() 完成后发射

"变更感知"请改用确实会 fire 的事件:EntityAdded / EntityModified / EntityDeleted / SelectionChanged / CommandEnded(见 bus-entity)。

二、entity:added

const bus = mapcadLayer.eventBus;
bus.on(VjmapextEvents.EntityAdded, ({ entity }) => {
  console.log('新增实体', entity.id, entity.type);   // 每次 addEntity 都 fire
});

EntityAdded payload 形如 { entity }(entity 带 id / type / color / layerId 等)。同族还有 EntityDeleted / EntityModified(见 bus-entity)。

三、自动保存 / Dirty 标记

let dirty = false;
bus.on(VjmapextEvents.EntityAdded, () => { dirty = true; });
bus.on(VjmapextEvents.EntityModified, () => { dirty = true; });
bus.on(VjmapextEvents.EntityDeleted, () => { dirty = true; });

setInterval(async () => {
  if (!dirty) return;
  dirty = false;
  await saveToServer(mapcadLayer.toJSON());
}, 5000);

四、undo 按钮状态

undo:changed 事件在 1.0.1 不存在;真实发射的是 undo:performed / redo:performed(UndoManager 直发,不在 VjmapextEvents 枚举内,用字面量订阅)。同步工具栏启用态:

function refreshUndoBtns() {
  myUndoBtn.disabled = !mapcadLayer.undoManager.canUndo;   // 你自己的 UI 按钮
  myRedoBtn.disabled = !mapcadLayer.undoManager.canRedo;
}
bus.on('undo:performed', refreshUndoBtns);
bus.on('redo:performed', refreshUndoBtns);
bus.on(VjmapextEvents.CommandEnded, refreshUndoBtns);

栈深无公共 API;用 undoManager.canUndo / canRedo 判断可用性(内部 undoStack 为私有字段,勿依赖)。

五、render:requested

1.0.1 中该事件不会被发射(枚举成员存在但 bundle 内无 emit 点),下面代码永远收不到回调:

bus.on(VjmapextEvents.RenderRequested, () => {
  // ⚠️ 死代码——事件定义存在但从未 fire
});

重绘由 EntityStore.requestRender() 内部调度驱动(标脏即入帧)。需要主动整帧重绘时可调公有方法 mapcadLayer.renderPipeline.forceFullRender()(renderPipeline 是 MapCadLayer 的公有 readonly 字段,内置 JsonPanel/ScriptRunner 都这么用);但仍没有"重绘完成"回调事件,render:requested 也不发射。

六、常见坑

  1. store:changed 永远收不到:1.0.1 未发射——若老代码订阅了它做 dirty 标记会失效,改挂 entity:*。
  2. 自动保存频率太高:实体事件每次 add 都 fire;加 debounce。
  3. UI 不刷新:可能监听了错事件;组件应监听 entity:* / selection:changed / command:ended。
  4. undo 栈 UI 不更新:1.0.1 没有 undo:changed;用 undo:performed / redo:performed / command:ended 刷新按钮态(store:changed 同样是死枚举,不要依赖)。

相关