事件主题 (vjmap + vjmapext)
本文回答:事件主题总览 —— vjmap
map.on/off+ vjmapexteventBus.on/off,覆盖视图 / 交互 / 生命周期 / 实体 / 命令。
两套事件体系:
| 来源 | 对象 | 用法 | 主要事件 |
|---|---|---|---|
| vjmap(底座) | map.on(type, handler) |
底座原生事件,一个 canvas 的所有鼠标 / 视图 / 生命周期 | click / move / zoom / load / styledata / render ... |
| vjmapext(扩展) | mapcadLayer.eventBus.on(event, handler) |
针对 CAD 实体 / 命令 / 输入 / 选集 | entity:added / command:started / selection:changed ... |
子项索引
| 文件 | 主题 |
|---|---|
| map-interaction | click / mousemove / dblclick / wheel / contextmenu ... |
| map-lifecycle | load / idle / sourcedata / styledata / render / error |
| map-view | move / moveend / zoom / rotate / pitch |
| layer-events | map.on('click', layerId, handler) 图层级绑定 |
| bus-entity | entity:added / deleted / modified / click / dblclick / mouseenter / mouseleave |
| bus-selection | selection:changed / boxselect:started / boxselect:ended |
| bus-command-mode | command:started / ended / mode:changed / input:started / ended |
| bus-render-store | undo:performed / redo:performed(store:changed / render:requested 枚举有定义但 1.0.1 未发射) |
| cleanup | off / once / clear 生命周期管理 |
最小代码
// vjmap 原生
map.on('click', e => console.log('点到:', e.lngLat));
map.on('click', 'my-layer', e => console.log('点到图层:', e.features[0]));
// vjmapext 事件总线
const { VjmapextEvents } = vjmapext;
mapcadLayer.eventBus.on(VjmapextEvents.EntityAdded, ({ entity }) => {
console.log('新增实体:', entity.id, entity.type);
});
mapcadLayer.eventBus.on(VjmapextEvents.SelectionChanged, ({ selectedIds }) => {
console.log('当前选中全集:', selectedIds); // 全集快照,无增量字段
});
mapcadLayer.eventBus.on(VjmapextEvents.CommandStarted, ({ name }) => {
console.log('开始命令:', name);
});
用哪一套?
- 要地图层面的事件(click / zoom / contextmenu / 图层要素 hover)→ map.on
- 要实体 / 命令 / 选集的事件 → mapcadLayer.eventBus
- 一般场景两套都用,各自订阅各自的,不要互相触发。
主题级 Top 5 陷阱
- 没
off导致泄漏:组件卸载时要逐一 off,或用eventBus.clear()一把梭。 - 匿名函数无法 off:保存 handler 引用再 off;或用
once。 entity:modified里又 modify:无限循环;用styleOnly标志或事务分组。map.on('click', ...)和map.on('click', 'layer', ...)同时触发:按注册顺序执行;MapMouseEvent 没有 stopPropagation,e.preventDefault()也拦不住其它监听——在全局 handler 里用queryRenderedFeatures(e.point, { layers })自查命中后跳过(见 layer-events §六)。- 命令执行中鼠标事件干扰命令输入流:命令期间忽略自定义鼠标处理或判断
mapcadLayer.commandRegistry.isCommandActive。
相关主题
- map.on 列表 → map-interaction
- 命令生命周期 → drawing/execute-command
- 实体增删改 → entity/lifecycle