ARTICLE DETAIL

资讯详情

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

lowcode-engine IPublicModelEditorView:窗口编辑视图模型、类型结构与多视图实现机制

lowcode-engine IPublicModelEditorView:窗口编辑视图模型、类型结构与多视图实现机制 lowcode-engine IPublicModelEditorView窗口编辑视图模型、类型结构与多视图实现机制【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engineIPublicModelEditorView是 lowcode-engine Workspace 多视图体系中的核心模型 API自 v1.1.7 引入标注为实验性它把「窗口中的一个编辑视图」抽象为独立的插件上下文既有完整插件上下文能力又携带viewName、viewType两个视图级标识。读完本篇你能理解该模型的类型结构、它在源码中的运行时实现内部 Context 与 Proxy 模型以及如何在工作区插件中获取并使用 EditorView 上下文来支持「编辑器 / Webview」双视图切换场景。一、API 参考定位一个带视图标识的插件上下文官方文档 editor-view.md 对该 API 的元信息定义如下状态experimental实验性 API类型文件IPublicModelEditorView版本since v1.1.7语义窗口编辑视图文档中给出的类型定义为import { IPublicModelPluginContext } from ./plugin-context; export interface IPublicModelEditorView extends IPublicModelPluginContext {};需要注意的是仓库中实际的类型声明比文档片段多出了两个字段以 packages/types/src/shell/model/editor-view.ts 为准import { IPublicModelPluginContext } from ./plugin-context; export interface IPublicModelEditorView extends IPublicModelPluginContext { viewName: string; viewType: editor | webview; }即IPublicModelEditorView的本质是IPublicModelPluginContext的扩展额外暴露视图名viewName与视图类型viewType取值为editor | webview。二、基座类型 IPublicModelPluginContextEditorView 继承的全部能力文档明确将 IPublicModelPluginContext 列为相关类型定义。从 plugin-context.ts 的源码看EditorView 上下文继承了以下成员均为 getter 或字段成员类型说明preferenceIPluginPreferenceMananger读取插件初始化配置skeletonIPublicApiSkeleton布局骨架 APIhotkeyIPublicApiHotkey快捷键 APIsettersIPublicApiSetters属性设置器 APIconfigIPublicModelEngineConfig引擎配置 APImaterialIPublicApiMaterial物料 APIeventIPublicApiEvent全局事件总线插件与引擎之间通信projectIPublicApiProject项目/画布文档 APIcommonIPublicApiCommon通用工具 APIpluginsIPublicApiPlugins插件管理 APIloggerIPublicApiLogger日志 APIpluginEventIPublicApiEvent插件内部局部事件不跨插件广播canvasIPublicApiCanvas画布 APIworkspaceIPublicApiWorkspace工作区 APIcommonUIIPublicApiCommonUI公共 UI APIcommandIPublicApiCommand命令 APIregisterLevelIPublicEnumPluginRegisterLevel插件注册层级since v1.1.7isPluginRegisteredInWorkspaceboolean是否注册在工作区层级editorWindowIPublicModelWindow所属窗口模型这也解释了 EditorView 的定位它不是一个新的能力集合而是把插件上下文的作用域收窄到某个具体视图使得该视图内注册的插件只拿到这一个上下文实例。三、viewName 与 viewType区分视图的两个字段3.1 viewType 的两种取值viewType只能是editor或webview默认值为editor。这一默认行为在源码中有多处印证内部视图上下文构造时执行this.viewType editorView.viewType || editor;view-context.tsWorkspace API 在枚举资源类型下的视图列表时同样做了viewType: d.viewType || editor的兜底api/workspace.ts 的resourceTypeList。两者的运行时行为差异体现在视图初始化流程中view-context.tsinit flow(function* (this: Context) { if (this.viewType webview) { // webview先取 url 钩子返回的地址再注册内置 webview 插件 const url yield this.instance?.url?.(); yield this.plugins.register(getWebviewPlugin(url, this.viewName)); } else { // editor注册内部插件骨架、模拟器等标准编辑器组件 yield this.registerInnerPlugins(); } yield this.instance?.init?.(); yield this.innerPlugins.init(); this.isInit true; });从源码结构看editor视图走标准编辑器装配注册内部插件而webview视图则退化为一个由url决定内容的内嵌页面viewName会作为 webview 插件的参数传入。3.2 viewName 与视图工厂类型viewName是视图在资源内的唯一名字资源层用它建立索引资源类维护editorViewMap: Mapstring, IPublicTypeEditorView初始化时把资源类型声明的每个editorViews项按viewName写入 Map并提供getEditorView(name)精确查找resource.ts资源的viewName属性解析顺序为resourceData.viewName → resourceData.viewType → defaultViewNameresource.ts其中defaultViewName又回退到资源类型的defaultViewName || defaultViewType用于决定窗口打开后默认展示哪个视图。viewName与viewType的组合还以「工厂函数」的形式暴露给资源类型声明侧即 IPublicTypeEditorViewexport interface IPublicTypeEditorView { /** 资源名字 */ viewName: string; /** 资源类型 */ viewType?: editor | webview; (ctx: any, options: any): IPublicEditorViewConfig; }它是一个「带元信息的函数」调用后返回 IPublicEditorViewConfig包含三个可选钩子export interface IPublicEditorViewConfig { /** 视图初始化钩子 */ init?: () Promisevoid; /** 资源保存时会调用视图的钩子 */ save?: () Promisevoid; /** viewType 类型为 webview 时渲染的地址 */ url?: () Promisestring; }其中url钩子仅在viewType为webview时生效对应上文 init 流程中的取值init/save则会在视图初始化与窗口save()调用链中被触发视图上下文的save()即return await this.instance?.save?.()见 view-context.ts。四、运行时实现内部 Context 与公开的 EditorView 模型4.1 内部ContextIViewContext真正的状态容器是 workspace 包中的 Context 类实现IViewContext它基于 mobx 的obx/computed/flow管理激活状态_activate/active与初始化标记isInit构造时以IPublicEnumPluginRegisterLevel.EditorView作为注册层级并调用视图工厂函数拿到instance即IPublicEditorViewConfig。setActivate还会联动innerHotkey.activate()保证快捷键只在激活的视图中生效——从源码结构看这是「每个视图拥有独立快捷键作用域」的实现基础。4.2 公开模型EditorView 类与 toProxy对外暴露的模型实现见 packages/shell/src/model/editor-view.tsexport class EditorView { [editorViewSymbol]: IViewContext; [pluginContextSymbol]: IPublicModelPluginContext; constructor(editorView: IViewContext) { this[editorViewSymbol] editorView; this[pluginContextSymbol] this[editorViewSymbol].innerPlugins._getLowCodePluginContext({ pluginName: editorView.editorWindow editorView.viewName, }); } toProxy() { return new Proxy(this, { get(target, prop, receiver) { if ((target[pluginContextSymbol] as any)[prop as string]) { return Reflect.get(target[pluginContextSymbol], prop, receiver); } return Reflect.get(target, prop, receiver); }, }); } get viewName() { return this[editorViewSymbol].viewName; } get viewType() { return this[editorViewSymbol].viewType; } }三个关键点上下文来源构造时用「窗口标识 viewName」拼出唯一的pluginName从内部插件系统取出对应的低代码插件上下文保证 EditorView 上下文与视图内注册的插件一一对应Proxy 代理策略toProxy()生成的代理在属性访问时优先委托给pluginContextSymbol只有插件上下文上不存在该属性时才回落到 EditorView 自身即viewName、viewType这两个视图级字段。这正是「IPublicModelEditorView extends IPublicModelPluginContext」在运行时的落地方式——一个对象同时满足两个接口的读取字段只读性viewName、viewType只暴露 getter视图标识由声明侧决定运行时不可改写。五、与 Window 模型的配合多视图切换的入口IPublicModelEditorView的挂载点在 IPublicModelWindow同为 v1.1.7 引入export interface IPublicModelWindowResource IPublicModelResource { /** 窗口当前视图 */ currentEditorView: IPublicModelEditorView | null; /** 窗口全部视图实例 */ editorViews: IPublicModelEditorView[]; /** 修改当前窗口视图类型 */ changeViewType(viewName: string): void; /** 调用当前窗口视图保存钩子 */ save(): Promiseany; /** 窗口视图变更事件 */ onChangeViewType(fn: (viewName: string) void): IPublicTypeDisposable; /** 窗口视图保存事件 since 1.1.7 */ onSave(fn: () void): IPublicTypeDisposable; // ...id / title / icon / resource / importSchema }据此窗口是「视图的宿主」editorViews持有该窗口资源声明的所有视图实例currentEditorView指向当前激活视图未就绪时为nullchangeViewType(viewName)完成切换save()触发当前视图的save钩子onChangeViewType/onSave则提供可订阅、可dispose的事件通道。视图声明本身则来自资源体系——resourceTypeList API 会把每个资源类型的editorViews以{ viewName, viewType }列表形式对外暴露可作为枚举「某资源支持哪些视图」的入口窗口打开由workspace.openEditorWindow系列方法驱动api/workspace.ts。六、实战在插件中获取并使用 EditorView 上下文lowcode-utils 提供了专门的高阶组件 ProvideViewPluginContext用于把「当前视图」的 EditorView 上下文注入到 React 组件中// packages/utils/src/workspace.tsx 核心逻辑简化 const getPluginContextFun (editorWindow?) { if (!editorWindow?.currentEditorView) return null; if (viewName) { // 按字符串或字符串数组过滤特定视图 const items editorWindow?.editorViews.filter(d d.viewName viewName || (Array.isArray(viewName) viewName.includes(d.viewName))); return items[0]; } return editorWindow.currentEditorView; };其工作方式有三个值得注意的细节均见源码支持传入viewName字符串或字符串数组来锁定特定视图的上下文不传则跟随currentEditorView通过workspace.onChangeActiveEditorView监听视图切换并自动更新注入的上下文workspace.tsx仅当宿主组件的registerLevel为IPublicEnumPluginRegisterLevel.Workspace时才注入否则原样渲染避免非工作区插件误用视图上下文。基于这些 API一个典型的视图状态组件可以写成import { ProvideViewPluginContext } from alilc/lowcode-utils; import { IPublicModelEditorView } from alilc/lowcode-types; function ViewStatus({ pluginContext }: { pluginContext: IPublicModelEditorView }) { return ( span {pluginContext.viewName} / {pluginContext.viewType} /span ); } // 将名为 custom-view 的视图上下文注入组件 export default ProvideViewPluginContext(ViewStatus, custom-view);对于非组件场景如命令、事件处理可直接经由窗口模型操作// 工作区层级插件中 const win pluginContext.workspace.window; console.log(win.currentEditorView?.viewName, win.currentEditorView?.viewType); const disposable win.onChangeViewType((viewName) { // 当前窗口视图切换时回调 }); // 不再需要时 disposable.dispose();若声明自定义视图则在资源类型模型中提供editorViews数组每项遵循 IPublicTypeEditorView 的形状例如一个 webview 预览视图示例{ viewName: preview-webview, viewType: webview, (ctx, options) { return { url: async () options.url, // 仅 webview 视图生效 }; }, },资源初始化时会将其登记进editorViewMapresource.ts随后窗口即可通过changeViewType(preview-webview)切入该视图。七、限制与注意事项实验性 API文档页明确标注experimental且viewType/currentEditorView/editorViews均要求v1.1.7 及以上在旧版本或非 Workspace 模式下registerLevel非Workspace这些字段与ProvideViewPluginContext的注入行为不可用。文档与源码的差异editor-view.md 中的接口体是空的extends IPublicModelPluginContext {}而仓库类型声明实际包含viewName、viewType两个字段引用类型时以 editor-view.ts 的源码为准。null 安全currentEditorView的类型为IPublicModelEditorView | null视图尚未初始化或窗口无资源时可能为空使用前应判空ProvideViewPluginContext内部即如此处理。适用场景该模型服务于「一个窗口、多个视图」的资源化工作区如同时提供设计器视图与 webview 预览视图。单画布、单视图的普通编辑器接入不需要直接接触 EditorView 模型。参考文件API 文档docs/docs/api/model/editor-view.md类型声明packages/types/src/shell/model/editor-view.ts、packages/types/src/shell/model/plugin-context.ts、packages/types/src/shell/model/window.ts、packages/types/src/shell/type/editor-view.ts、packages/types/src/shell/type/editor-view-config.ts运行时实现packages/shell/src/model/editor-view.ts、packages/workspace/src/context/view-context.ts、packages/workspace/src/resource.ts、packages/shell/src/api/workspace.ts视图上下文注入工具packages/utils/src/workspace.tsx【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表