ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

lowcode-engine 文档模型 DocumentModel 完全指南:属性、方法、事件与源码级实现解析

lowcode-engine 文档模型 DocumentModel 完全指南:属性、方法、事件与源码级实现解析 lowcode-engine 文档模型 DocumentModel 完全指南属性、方法、事件与源码级实现解析【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine本文以 lowcode-engine 官方 API 文档中的 DocumentModel 文档 为核心主线系统讲解低代码引擎中文档模型DocumentModel的全部属性、方法、事件及其回调签名并逐一对应到 类型定义、Shell 层实现 与 Designer 核心实现 的源码帮助读者在开发插件、扩展引擎功能或深入理解低代码文档数据模型时能够准确使用 DocumentModel 这一核心 API。一、DocumentModel 是什么低代码文档的数据中枢在 lowcode-engine 的架构中一个文档Document对应一个正在被编辑的页面/组件/区块实例而 DocumentModel 就是这个文档在编辑器内存中的数据中枢模型。它统一管理文档的节点树、选区、悬停、操作历史、拖拽投放位置等状态并提供 Schema 导入导出、节点增删改查以及一系列文档级事件订阅能力。类型定义IPublicModelDocumentModel自 v1.0.0 起提供。Shell 层实现DocumentModel面向插件开发者暴露的封装实例。Designer 内部实现DocumentModel 类引擎运行时真正承载数据的模型。从源码结构上看IPublicModelDocumentModel是一个泛型接口Selection、History、Node、DropLocation、ModalNodesManager、Project六个类型参数均有默认值这意味着引擎内部IDocumentModel与外部 Shell 层可以使用不同的具体类型实现同一套协议这正是 lowcode-engine 面向扩展设计思想的体现见 document-model.ts。二、属性PropertiesDocumentModel 共提供 8 个公开属性覆盖文档身份、节点树、选区与悬停、历史、拖拽投放等核心状态。2.1 id文档唯一 ID项目说明类型string含义文档唯一 ID在 Designer 内部DocumentModel构造时通过uniqueId(doc)生成doc前缀的唯一 ID并兼容 vision 场景使用 schema 中的 id见 document-model.ts、document-model.ts。通过 Shell 层可读写该属性shell document-model.ts。2.2 selection画布节点选中区模型项目说明类型IPublicModelSelection含义画布节点选中区模型实例该实例管理当前文档中哪些节点被选中支持多选与选区变化监听。内部由new Selection(this)创建document-model.tsShell 层包装为ShellSelectionshell document-model.ts。相关章节见 节点选中区模型。2.3 detecting画布节点 hover 区模型项目说明类型IPublicModelDetecting含义画布节点 hover 区模型实例管理鼠标悬停hover探测状态。Shell 层构造时创建ShellDetectingshell document-model.ts。相关章节见 画布节点悬停模型。2.4 history操作历史模型项目说明类型IPublicModelHistory含义操作历史模型实例支撑撤销/重做。内部实现中History的构造参数以序列化导出与导入回放两个回调闭环工作保存点时导出Serilize阶段的 schema回放时重新 import 并触发模拟器重渲染document-model.ts。相关章节见 操作历史模型。2.5 project所属 Project项目说明类型IPublicApiProject含义获取当前文档模型所属的 project一个 Project 可包含多个 Document多页面场景通过该属性可反向访问项目级 APIshell document-model.ts。2.6 root文档根节点项目说明类型IPublicModelNode \| null含义获取文档的根节点根节点类型通常为Page/Component/Block源码注释见 document-model.ts。当文档为空无 schema 构造时返回null。Shell 层通过ShellNode.create包装返回shell document-model.ts。2.7 nodesMap全量节点 Map项目说明类型Mapstring, IPublicModelNode含义文档下所有节点 Mapkey 为 nodeId内部维护_nodesMap每个节点创建时都会注册进来document-model.ts、document-model.ts。Shell 层在读取时会重新构造一个以 nodeId 为 key、ShellNode 为 value 的新 Mapshell document-model.ts。2.8 modalNodesManager模态节点管理器项目说明类型IPublicModelModalNodesManager \| null含义模态节点管理器用于管理弹窗、抽屉等模态类节点如 Dialog 类型节点的注册与调度。内部在构造阶段new ModalNodesManager(this)创建document-model.ts。相关章节见 模态节点管理。2.9 dropLocation拖拽投放位置v1.1.0项目说明类型IPublicModelDropLocation \| null含义文档当前的 dropLocation版本since v1.1.0set dropLocation时不仅更新内部_dropLocation还会向全局事件总线派发document.dropLocation.changed事件document-model.ts这也是onDropLocationChanged事件的底层来源。补充除上述公开属性外内部实现还提供fileName、focusNode聚焦节点可由插件手动设置、suspensed/active激活状态等扩展状态感兴趣可查阅 document-model.ts。三、方法Methods3.1 getNodeById按 nodeId 获取节点getNodeById(nodeId: string): IPublicModelNode | null;按 nodeId 从_nodesMap中取节点内部即getNodedocument-model.tsShell 层包装为 ShellNode 返回未命中返回nullshell document-model.ts。3.2 importSchema导入 SchemaimportSchema(schema: IPublicTypeRootSchema): void;将整棵 schema 树导入当前文档重建文档内容。底层实现import(schema, checkId)采用饱和式删除 根节点导入策略先移除所有非根节点含无法按树递归的 Slot 节点再让根节点导入新 schema并重建modalNodesManagerdocument-model.ts。Shell 层导入成功后还会广播shell.document.importSchema事件shell document-model.ts。schema参数类型为 IPublicTypeRootSchema即PageSchema | ComponentSchema | BlockSchema的联合类型。3.3 exportSchema导出 SchemaexportSchema(stage: IPublicEnumTransformStage): IPublicTypeRootSchema | undefined;以指定转换阶段导出文档 schema默认阶段为RenderShell 层默认值shell document-model.ts。内部实现export会处理置顶节点逻辑将带props.__isTopFixed__标记的 Page 第一级子节点提到 children 首位document-model.ts。stage的可选值由 IPublicEnumTransformStage 定义枚举值含义典型用途render渲染阶段交给渲染器/模拟器渲染serilize序列化阶段历史记录保存点、持久化save保存阶段保存到后端含 componentsMap 等clone克隆阶段节点/文档复制init初始化阶段文档首次装载upgrade升级阶段schema 版本升级3.4 insertNode插入节点insertNode( parent: IPublicModelNode, thing: IPublicModelNode, at?: number | null | undefined, copy?: boolean | undefined ): IPublicModelNode | null;向指定父节点插入节点parent目标父节点thing待插入的节点实例内部实现同时兼容直接传 schema 数据见 document-model.tsat插入的索引位置缺省时追加到末尾copy是否复制插入。底层委托insertChild(parent, thing, at, copy)完成插入返回实际插入后的节点Shell 层负责把外部的 ShellNode 转换回内部节点再执行shell document-model.ts。3.5 createNode创建节点createNode(data: any): IPublicModelNode | null;根据节点数据schema创建节点并注册进nodesMap随后触发内部nodecreate事件对应onAddNode。内部实现还做了去重与文本/表达式兼容若传入的是 DOM 文本或 JSExpression会包装成componentName: Leaf的叶子节点document-model.ts。注意createNode 仅创建节点若需挂载到树上请结合insertNode使用。3.6 removeNode移除节点removeNode(idOrNode: string | IPublicModelNode): void;既支持传 nodeId 字符串也支持传节点实例内部统一解析出节点后执行internalRemoveAndPurgeNode先node.remove()再清理引用document-model.ts。3.7 checkNesting拖拽嵌套合法性检查v1.0.16checkNesting( dropTarget: IPublicModelNode, dragObject: IPublicTypeDragNodeObject | IPublicTypeDragNodeDataObject ): boolean;检查拖拽放置的目标节点dropTarget是否允许放置该拖拽对象dragObject返回布尔值。底层同时执行两类校验document-model.tscheckNestingUp检查对象对父级的要求对应组件元信息配置parentWhitelist父级白名单checkNestingDown检查投放位置对子级的要求对应组件元信息配置childWhitelist子级白名单。dragObject的两种类型定义见 IPublicTypeDragNodeObject已存在的节点数组type: node与 IPublicTypeDragNodeDataObject待创建的节点 schema 数据type: nodedata。该场景还保留有被标记 deprecated 的旧接口checkDropTarget将在 2.0.0 移除document-model.ts。3.8 isDetectingNode节点是否处于探测状态v1.1.0isDetectingNode(node: IPublicModelNode): boolean;判断传入节点是否为当前被 hover 探测的节点。Shell 层实现直接对比this.detecting.current nodeshell document-model.ts。四、事件EventsDocumentModel 的所有onXxx订阅方法都返回一个 IPublicTypeDisposable即() void清理函数在插件卸载或页面销毁时调用它即可取消订阅避免内存泄漏。这是 lowcode-engine 事件订阅的统一约定。4.1 onAddNode新增节点onAddNode(fn: (node: IPublicModelNode) void): IPublicTypeDisposable;当 document 新增节点节点被创建并注册进 nodesMap时触发。Shell 层委托内部onNodeCreate订阅内部nodecreate事件并把内部节点转换为 ShellNode 后回调shell document-model.ts。4.2 onMountNode节点挂载完成onMountNode(fn: (payload: { node: IPublicModelNode }) void): IPublicTypeDisposable;节点已挂载到 document画布上时触发回调参数为{ node }结构。内部监听全局事件总线node.add事件document-model.ts。4.3 onRemoveNode删除节点onRemoveNode(fn: (node: IPublicModelNode) void): IPublicTypeDisposable;当 document 删除节点时触发。Shell 层委托内部onNodeDestroy订阅内部nodedestroy事件shell document-model.ts。4.4 onChangeDetectinghover 变更onChangeDetecting(fn: (node: IPublicModelNode) void): IPublicTypeDisposable;文档 hover 探测节点变化时触发回调携带当前 hover 的节点。Shell 层订阅内部designer.detecting.onDetectingChangeshell document-model.ts。4.5 onChangeSelection选中变更onChangeSelection(fn: (ids: string[]) void): IPublicTypeDisposable;文档选中区变化时触发回调参数为当前选中的节点 ID 数组。Shell 层订阅内部selection.onSelectionChangeshell document-model.ts。4.6 onChangeNodeVisible节点显隐变更onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) void): IPublicTypeDisposable;节点显隐状态变化时触发回调同时携带节点与visible布尔值。内部基于全局事件NODE_VISIBLE_CHANGE实现document-model.ts。4.7 onChangeNodeChildren节点 children 变更onChangeNodeChildren(fn: (info?: IPublicTypeOnChangeOptions) void): IPublicTypeDisposable;节点 children 结构变化时触发。回调参数类型为 IPublicTypeOnChangeOptions包含type变更类型与node发生变更的节点。内部基于全局事件NODE_CHILDREN_CHANGE实现document-model.tsShell 层将内部节点包装为 ShellNode 后回调shell document-model.ts。4.8 onChangeNodeProp节点属性修改onChangeNodeProp(fn: (info: IPublicTypePropChangeOptions) void): IPublicTypeDisposable;文档内节点属性修改时触发。回调参数类型为 IPublicTypePropChangeOptions包含key、prop、node、newValue、oldValue等字段。Shell 层订阅全局Node.Prop.InnerChange事件并组装以上字段shell document-model.ts。4.9 onImportSchema导入 Schema 事件v1.0.15onImportSchema(fn: (schema: IPublicTypeRootSchema) void): IPublicTypeDisposable;当前 document 导入新 schema 时触发回调携带导入的 schema。Shell 层在importSchema()成功后广播shell.document.importSchema本事件即订阅该广播shell document-model.ts。4.10 onFocusNodeChanged聚焦节点变化v1.1.0onFocusNodeChanged( fn: (doc: IPublicModelDocumentModel, focusNode: IPublicModelNode) void, ): IPublicTypeDisposable;聚焦节点focusNode被插件手动设置时触发回调携带文档与新的聚焦节点。底层对应 Shell 层set focusNode时广播的shell.document.focusNodeChanged事件shell document-model.ts、shell document-model.ts。4.11 onDropLocationChangedDropLocation 变化v1.1.0onDropLocationChanged(fn: (doc: IPublicModelDocumentModel) void): IPublicTypeDisposable;文档的 DropLocation 变化时触发回调携带文档本身。底层订阅document.dropLocation.changed事件——该事件正是dropLocation属性 setter 派发的document-model.ts、shell document-model.ts。五、实战示例在插件中综合使用 DocumentModel以下示例展示在插件上下文中如何组合使用 DocumentModel 的属性、方法与事件实现监听文档变化 结构化访问节点树 安全插入节点的典型场景import { IPublicModelPluginContext } from alilc/lowcode-types; const DocumentModelDemoPlugin (ctx: IPublicModelPluginContext) { return { name: document-model-demo, async init() { const { project } ctx; // 1. 文档装载完成后拿到 documentModel project.onSimulatorReady(() { const doc project.currentDocument; if (!doc) return; // 2. 属性访问根节点 全量节点 const root doc.root; const allNodes doc.nodesMap; console.log(doc id:, doc.id, root:, root?.componentName, nodeCount:, allNodes.size); // 3. 订阅关键事件返回 disposable卸载时调用 const disposables [ doc.onChangeSelection((ids) console.log(selection:, ids)), doc.onMountNode(({ node }) console.log(mounted:, node.componentName)), doc.onChangeNodeProp((info) console.log(prop changed:, info.key, info.oldValue, -, info.newValue)), doc.onImportSchema((schema) console.log(schema imported:, schema.componentName)), ]; // 4. 通过方法进行节点操作创建并插入一个容器节点 const parent doc.getNodeById(root?.id); if (parent) { const container doc.createNode({ componentName: Div, props: { className: demo-wrapper }, }); doc.insertNode(parent, container!, 0); // 插入到第 0 个位置 } // 5. 导出渲染阶段 schema const schema doc.exportSchema(render); // 6. 插件销毁时统一取消订阅 return () disposables.forEach((dispose) dispose()); }); }, }; }; export default DocumentModelDemoPlugin;要点说明取消订阅所有onXxx返回的 IPublicTypeDisposable 建议在插件destroy阶段统一执行插入前校验如需在拖拽/编程式插入前判断合法性可调用doc.checkNesting(dropTarget, dragObject)事件顺序onAddNode在节点创建并注册时触发onMountNode在节点真正挂载到画布后触发两者时机不同按需选择。六、小结DocumentModel 的能力全景与扩展指引维度能力涉及成员身份与归属文档 ID、所属 Projectid、project节点树访问根节点、全量节点 Map、按 ID 查询root、nodesMap、getNodeById状态模型选区、hover、历史、模态节点、投放位置selection、detecting、history、modalNodesManager、dropLocation数据流转Schema 导入/导出importSchema、exportSchema、onImportSchema节点操作创建、插入、移除、嵌套校验createNode、insertNode、removeNode、checkNesting、isDetectingNode事件订阅节点增删挂载、选区/hover/显隐/children/属性变化、聚焦与投放变化onAddNode~onDropLocationChanged共 11 个DocumentModel 是连接页面 Schema 数据与编辑器交互状态的枢纽向上通过project关联项目向下通过root/nodesMap关联具体节点向外部通过事件流通知插件感知文档的每一次变化。开发者可以沿着以下路径继续深入节点层面的能力参考 节点模型 Node 与 节点 children 模型状态模型细节参考 节点选中区模型、画布节点悬停模型、操作历史模型 与 模态节点管理引擎内部完整实现可阅读 DocumentModel 核心类 及其配套的 selection.ts、history.ts 与 modal-nodes-manager.ts。【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表