唯杰地图 logo唯杰地图
VJMAP
EN

文档 / 示例 / 源码命名不一致的坑

vjcad/references/trouble/source-conflicts.md 8.5 KB207 行
原文

这一页专门收录 vjcad 的"两种 / 三种说法都对"的地方。开发时被绕进去 → 来这里翻一下。

vjcad 是高频迭代的产品,官方文档 / 官方在线示例 / 实际类型 偶有命名 / 签名差异。本文按"碰到的命名歧义"归档。

⚠️ 原则:以示例代码(vjcad/example/...)能跑为准;文档作为"理解性参考"。

1. viewMode vs viewerMode

来源 写法
文档(部分页面) viewerMode: true
示例 / 类型 viewMode: 'viewer'

✅ 正解:

new MainView({ viewMode: 'viewer' });   // 'full' | 'viewer'(完整编辑器 | 只读查看器)

viewerMode 在源码、types.d.ts 与 vjcad@1.0.16 打包产物中都不存在,传了会被静默忽略(不报错也不生效);只能用 viewMode。

2. entity.type 值:'PLINE' vs 'LWPOLYLINE'

实体 type 字段为大写类型名,但 PolylineEnt 是最容易踩的坑:

类 type 字段(当前版本)
LineEnt 'LINE'
CircleEnt 'CIRCLE'
ArcEnt 'ARC'
PolylineEnt 'PLINE' ⚠️ 不是 'LWPOLYLINE'
TextEnt 'TEXT'
MTextEnt 'MTEXT'
HatchEnt 'HATCH'
InsertEnt 'INSERT'

'LWPOLYLINE' 的合法位置:EntityTypeFilter 过滤器词表(QuickSelect 相关 API 入参,与 POLYLINE 并列,types.d.ts 可查)与兼容判断代码——源码 PatternMatchService/BoundaryDetector/TableExtractUtils 等 6 处都有 type === 'PLINE' || 'LWPOLYLINE'(甚至 || 'POLYLINE')的双匹配,用于兼容 DWG 导入/旧版本数据。运行时新建的 PolylineEnt 恒为 'PLINE'(构造函数写死),你自己代码里的类型判断只写 'PLINE' 即可。

Engine.getEntitiesByType('LINE');      // ✅
Engine.getEntitiesByType('PLINE');     // ✅ 多段线用这个
Engine.getEntitiesByType('LWPOLYLINE');// ❌ 当前实体永远不匹配(除非读老存档)
Engine.getEntitiesByType('Line');      // ❌ 找不到(内部 === 精确匹配,只做了 toUpperCase)
Engine.getEntitiesByType('LineEnt');   // ❌

3. entity.id 是 string 还是 number?

不同子类 / 不同文档说法:

  • architecture.md:entity.id: string
  • api-reference.md:entity.id: number

实际:vjcad 内部是数字递增 ID,但 跨网络传输 / 序列化时通常字符串化(与 handle 一致)。

✅ 安全做法:

String(entity.id)         // 永远用字符串比较
String(otherEntity.id) === String(entity.id)

不要直接 === 比较,避免类型不一致。

4. entity.move(dx, dy) 还是 entity.move(from, to)

来源 用法
文档 edit/edit-commands.md entity.move(dx, dy) 相对位移
示例 edit/01move.js entity.move(fromPoint, toPoint) 绝对两点

✅ 以示例为准:

entity.move([0, 0], [100, 50]);     // 从原点移到 (100, 50)

如果你看到文档说 move(dx, dy),那是历史接口,未必在最新版生效。

5. 坐标转换的多种入口

写法 说明
Engine.canvasToWcs(p) 顶层静态快捷(小写开头)
Engine.trans.CanvasToWcs(p) CoordinateTransform 实例方法(大写开头)
Engine.pcanvas.trans.CanvasToWcs(p) 同一条 CoordinateTransform 链路

⚠️ 注意大小写不对称:Engine 静态方法是 canvasToWcs(小写),CoordinateTransform 实例方法是 CanvasToWcs(大写,配套 WcsToCanvas/DcsToWcs/WcsToDcs…)。写错大小写就是 undefined is not a function。

// 推荐:顶层
const wcs = Engine.canvasToWcs(canvasPoint);

不要混用,否则代码看起来"工程师不理解"。

6. Reactor 注册的真实入口

EntityReactorManager 只提供 registerReactor(reactor: IEntityReactor, docId?) / unregisterReactor(reactorId, docId?)——没有 entity.setReactor(r) 也没有 register({owner,target,onChange}) 配置对象形态(老资料里的两种写法都不存在)。

✅ 正确姿势:自定义实体实现 IEntityReactor(getOwnerIds/updateFromOwners/...),Engine.reactorManager.registerReactor(myReactorEnt, docId)。详见 reactor/ireactor-interface.md。

7. Engine.lineTypeManager vs Engine.linetypeManager

驼峰拼写不一致:

  • 文档:Engine.linetypeManager
  • 类型定义(types.d.ts):Engine.linetypeManager

1.0.16 的 types.d.ts 里只有 linetypeManager(小写 t)。统一用 linetypeManager,不要写 lineTypeManager。

8. Engine.zoomExtents() vs Engine.pcanvas.zoomExtents()

二者等价 —— Engine.zoomExtents 是顶层静态快捷,Engine.pcanvas(CanvasController)上的同名方法也直接可调。注意是 pcanvas 不是 view:MainView 上没有 zoomExtents。

Engine.zoomExtents();                // 推荐
Engine.pcanvas.zoomExtents();        // 等价

9. LineEnt(p1, p2) —— 位置参数是唯一构造形式

vjcad 实体构造函数全部是位置参数(首参几何、末参可选 color),没有 new LineEnt({ start, end }) 这类对象式签名:

new LineEnt([0, 0], [100, 0]);        // ✅ 点参数支持 [x,y] 数组或 Point2D
new LineEnt({ start: [0,0] });        // ❌ 不存在——会得到 startPoint=NaN 的实体

示例代码中怎么写就怎么用,不要自创签名。

10. mapbounds 字符串 vs 数组

// ❌ 数组
mapbounds: [minX, minY, maxX, maxY]

// ✅ 字符串
mapbounds: 'minX,minY,maxX,maxY'

文档少数早期页面写成数组形式,实际 API 是字符串。

11. appendItems / prependItems 顺序

ContextMenuOpening 的两个数组:

events.on(CadEvents.ContextMenuOpening, args => {
    args.prependItems.push(item);     // 加到默认菜单的最前
    args.appendItems.push(item);      // 加到默认菜单的最后
});

注意 prependItems 是 数组顺序就是显示顺序(先 push 的更靠前)。不是 unshift 语义。

12. setLoops(HatchEnt 唯一正确 API)

hatch.setLoops(edges);     // ✅ 当前包中唯一存在的边界 API
hatch.setBoundary(edges);  // ❌ 不存在(d.ts/运行时均无)——老资料里的写法会直接 TypeError

13. lineType(唯一正确写法,linetypeName 不存在)

写法 用途
entity.lineType 官方 get/set 属性——读返回线型名,写接受 CONTINUOUS/别名/自定义名(内部转大写匹配)
entity.linetypeName ❌ 不存在(d.ts/运行时均无),赋值只是挂了个无效字段
line.lineType = 'HIDDEN';   // ✅

14. EntityErasing 与 EntityErased

vjcad 的事件命名:

  • EntityErasing / EntityErased:枚举里有,但 vjcad@1.0.16 从不派发(订阅永不触发)
  • 实际派发的是批量版 EntitiesErasing(可 cancel,或往 args.excludeEntities 里放部分实体)/ EntitiesErased

被某些社区文章误写成 EntityRemoving / EntityDeleted,请以 vjcad 类型 / 示例为准。

15. 总体策略

来源 可信度 用法
vjcad/example/*.js ⭐⭐⭐⭐⭐ 第一优先级
TypeScript 类型 ⭐⭐⭐⭐ 接口 / 字段
文档 (vjcad/doc/) ⭐⭐⭐ 概念解释
网上零散文章 ⭐ 仅参考思路

红旗

  • 当文档与示例冲突时,信示例
  • 看到驼峰大小写不一致时,任选一种贯彻整个项目
  • 看到"参数顺序" / "签名"歧义时,先 Object.getOwnPropertyNames(EntityClass.prototype) 看真实方法
  • 不要为"接口看起来更好看"而自创不存在的签名 —— 类型擦除后只剩字符串,编译器不会救你
  • 老文档可能有效但不是"最佳实践",新功能(如 viewMode、reactorManager)始终用新 API

参考(官方文档 MCP)

  • 本页内容来自实际写本 skill 时遇到的歧义对照,相关文档与示例在每条小节内已标注:vjcad/doc/guide/architecture.md、vjcad/doc/command/api-reference.md、vjcad/doc/edit/edit-commands.md、vjcad/doc/ui/dialogs.md、vjcad/doc/event/event-types.md 等
  • 示例对照:vjcad/example/basic/04viewerremote.js、vjcad/example/edit/01move.js、vjcad/example/entity/dimension/09associative.js 等