ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

NocoBase RunJS 深度指南:ctx.blockModel 让 JSField / JSItem / JSColumn 访问父区块的 form、collection 与 resource

2026/9/17 14:18:29 拓冰建站 浏览量
NocoBase RunJS 深度指南:ctx.blockModel 让 JSField / JSItem / JSColumn 访问父区块的 form、collection 与 resource NocoBase RunJS 深度指南ctx.blockModel 让 JSField / JSItem / JSColumn 访问父区块的 form、collection 与 resource【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase本篇基于 NocoBase 官方 RunJS 上下文文档 block-model.md 展开讲清ctx.blockModel的定位——当前 JS 字段 / JS 区块所在的父区块模型BlockModel实例以及它在 JSField、JSItem、JSColumn 场景中访问父表单/表格区块的form、collection、resource的完整用法。读完你能够在字段级联动、表格行操作、表单校验与刷新等场景下正确取用父区块能力理解ctx.blockModel与ctx.model、ctx.form、ctx.resource的分工并从源码层面确认它的注入时机与空值边界。一、ctx.blockModel 是什么ctx.blockModel指向承载当前 JS 逻辑的父区块即 NocoBase 客户端区块模型BlockModel的运行时实例。具体含义随 JS 载体而变在JSField、JSItem、JSColumn中它指向承载当前 JS 逻辑的表单区块或表格区块在JSBlock 独立区块中它可能为null或与ctx.model相同即区块自身。它的核心定位是从字段/列/子项的视角向上看一层JS 逻辑本身通常挂在字段或列上而数据刷新、选中行、表单实例等能力都定义在区块上ctx.blockModel就是这条访问链。官方类型定义为blockModel: BlockModel | FormBlockModel | TableBlockModel | CollectionBlockModel | DataBlockModel | null;具体类型取决于父区块类型表单区块多为FormBlockModel、EditFormModel表格区块多为TableBlockModel。二、ctx.blockModel 如何被注入源码依据从源码结构看ctx.blockModel并非静态属性而是在区块模型初始化时动态挂载到执行上下文上的。NocoBase 客户端 v2 的区块基类 BlockModel.tsx 在onInit中完成了这一注入onInit(options: any): void { super.onInit(options); this.context.defineProperty(blockModel, { value: this, }); // ... }也就是说只要某个区块BlockModel 子类初始化了自身的 flow context其context.blockModel就会被固定为该区块实例。CollectionBlockModel.tsx 对数据类区块做了同样的挂载并在数据加载逻辑中大量使用ctx.model上的resource与数据加载模式getDataLoadingMode()、hasActiveFilters()这解释了为什么文档中resource.refresh()等能力仅在数据区块下存在。另一处关键证据在 flow-engine 侧flowContext.ts 中通过context?.blockModel m判断一个模型是否为自身即区块的实例并在多处如 L1063 附近以getMaybe(() (evalCtx as any).blockModel)安全读取该属性。这印证了文档的两条注意事项独立 JSBlock 无父区块时ctx.blockModel可能为null使用前应做空值判断在 JSBlock 中它可能为自身或上层区块取决于实际层级——源码用context?.blockModel m这种比较正是为了区分自身即父区块的情况。此外BlockModel基类还定义了区块场景枚举 BlockSceneEnumnew/one/many/select/filter/subForm/bulkEditForm从源码结构看父区块处于哪种场景会影响 JSField 内可用的字段与联动语义这也是具体类型取决于父区块类型背后的实现背景。三、适用场景场景说明JSField表单字段内访问父表单区块的form、collection、resource实现联动或校验JSItem子表格项中访问父表格/表单区块的资源、数据表信息JSColumn表格列中访问父表格区块的resource如getSelectedRows、collection表单操作 / 事件流访问form做提交前校验、resource做刷新等注意ctx.blockModel仅在存在父区块的 RunJS 上下文中可用独立 JSBlock无父表单/表格时可能为null使用前建议做空值判断。四、常用属性属性类型说明uidstring区块模型唯一标识collectionCollection当前区块绑定的数据表resourceResource区块使用的资源实例SingleRecordResource/MultiRecordResource等formFormInstance表单区块Ant Design Form 实例支持getFieldsValue、validateFields、setFieldsValue等emitterEventEmitter事件发射器可监听formValuesChange、onFieldReset等几点使用边界与官方文档注意事项一致resource仅在数据区块下存在——源码中数据加载、刷新逻辑确实都挂在CollectionBlockModel及其resource上见 CollectionBlockModel.tsx 中对blockModel.resource、getDataLoadingMode()的调用form仅在表单区块下存在表格区块通常无form属性不存在时用可选链访问是最安全的写法例如ctx.blockModel?.resource?.refresh?.()。五、与 ctx.model、ctx.form 的关系三个入口各司其职官方推荐用法如下需求推荐用法当前 JS 所在的父区块ctx.blockModel读写表单字段ctx.form等价于ctx.blockModel?.form表单区块下更便捷当前执行上下文所在模型ctx.modelJSField 中为字段模型JSBlock 中为区块模型在 JSField 中ctx.model为字段模型ctx.blockModel为承载该字段的表单/表格区块ctx.form通常即ctx.blockModel.form。换言之需要我这条 JS 属于哪个区块→ 用ctx.blockModel需要我当前操作的对象是字段还是区块→ 用ctx.model需要读写字段值 → 表单区块下直接用ctx.form更便捷其余场景走ctx.blockModel?.form。ctx.resource同理等价于ctx.blockModel?.resource有则直接使用参见 ctx.resource 文档。六、实战示例以下示例完整继承自官方文档可直接用于 JSField / JSColumn / JSAction 的脚本中。表格获取选中行并处理在表格区块的 JSColumn 或行操作场景中通过父表格区块的resource取当前选中的行const rows ctx.blockModel?.resource?.getSelectedRows?.() || []; if (rows.length 0) { ctx.message.warning(请先选择数据); return; }表单场景校验并刷新提交前校验整个表单成功后刷新区块数据。validateFields()来自父表单区块的 Ant Design Form 实例resource.refresh()来自数据区块的资源实例if (ctx.blockModel?.form) { await ctx.blockModel.form.validateFields(); await ctx.blockModel.resource?.refresh?.(); }监听表单变化通过区块模型上的事件发射器监听表单值变化做联动或重新渲染。这类用法在 NocoBase 内部也被广泛使用——例如 dataScopeFormValueClear.test.ts 等测试用例就以blockModel: formBlock构造上下文验证表单值变化驱动数据范围清理等联动行为flow-engine 侧的 flowContext.test.ts 也定义了BlockModelLike等桩模型来验证ctx.blockModel的上下文解析ctx.blockModel?.emitter?.on?.(formValuesChange, (payload) { // 根据最新表单值做联动或重新渲染 });触发区块重新渲染ctx.blockModel?.rerender?.();七、注意事项完整清单空值防御ctx.blockModel在独立 JSBlock无父表单/表格区块时可能为null访问其属性前建议使用可选链ctx.blockModel?.resource?.refresh?.()。载体差异在JSField / JSItem / JSColumn中ctx.blockModel为承载当前字段的表单或表格区块在JSBlock中可能为自身或上层区块取决于实际层级源码以context?.blockModel m判断自身即父区块见 flowContext.ts。属性存在性resource仅在数据区块下存在form仅在表单区块下存在表格区块通常无form。八、源码与测试索引内容路径区块基类与ctx.blockModel注入onInit中defineProperty(blockModel)BlockModel.tsx数据区块模型resource与数据加载模式CollectionBlockModel.tsx区块场景枚举BlockSceneEnumBlockModel.tsxflow-engine 对ctx.blockModel的读取与自身区块判定flowContext.tsctx.blockModel相关行为测试表单联动、数据范围清理dataScopeFormValueClear.test.tsRunJS 表单提交链路测试runjsFormSubmit.test.ts本上下文官方文档block-model.md九、相关文档ctx.model当前执行上下文所在模型ctx.form表单实例表单区块下常用ctx.resource资源实例等价于ctx.blockModel?.resource有则直接使用ctx.getModel()按 uid 获取其他区块模型RunJS 总览runjs 文档目录综合来看ctx.blockModel是 NocoBase RunJS 体系中字段级 JS 与区块级能力之间的桥梁字段脚本负责细粒度逻辑区块模型负责数据与表单资源。理解BlockModel.onInit的注入机制、CollectionBlockModel的资源语义以及独立区块可能为 null的边界就能在联动、校验、刷新、选中行处理等实战场景中正确、安全地使用它。【免费下载链接】nocobaseNocoBase is an open-source AI no-code platform for building business systems fast. Instead of generating everything from scratch, AI works on top of production-proven infrastructure and a WYSIWYG no-code interface, so you get both speed and reliability.项目地址: https://gitcode.com/GitHub_Trending/no/nocobase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考