news 2026/9/17 14:18:00

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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 场景中访问父表单/表格区块的formcollectionresource的完整用法。读完你能够:在字段级联动、表格行操作、表单校验与刷新等场景下正确取用父区块能力,理解ctx.blockModelctx.modelctx.formctx.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;

具体类型取决于父区块类型:表单区块多为FormBlockModelEditFormModel,表格区块多为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基类还定义了区块场景枚举 BlockSceneEnum(new/one/many/select/filter/subForm/bulkEditForm),从源码结构看,父区块处于哪种场景会影响 JSField 内可用的字段与联动语义,这也是"具体类型取决于父区块类型"背后的实现背景。

三、适用场景

场景说明
JSField表单字段内访问父表单区块的formcollectionresource,实现联动或校验
JSItem子表格项中访问父表格/表单区块的资源、数据表信息
JSColumn表格列中访问父表格区块的resource(如getSelectedRows)、collection
表单操作 / 事件流访问form做提交前校验、resource做刷新等

注意:ctx.blockModel仅在存在父区块的 RunJS 上下文中可用;独立 JSBlock(无父表单/表格)时可能为null,使用前建议做空值判断。

四、常用属性

属性类型说明
uidstring区块模型唯一标识
collectionCollection当前区块绑定的数据表
resourceResource区块使用的资源实例(SingleRecordResource/MultiRecordResource等)
formFormInstance表单区块:Ant Design Form 实例,支持getFieldsValuevalidateFieldssetFieldsValue
emitterEventEmitter事件发射器,可监听formValuesChangeonFieldReset

几点使用边界(与官方文档"注意事项"一致):

  • resource仅在数据区块下存在——源码中数据加载、刷新逻辑确实都挂在CollectionBlockModel及其resource上(见 CollectionBlockModel.tsx 中对blockModel.resourcegetDataLoadingMode()的调用);
  • form仅在表单区块下存在,表格区块通常无form
  • 属性不存在时用可选链访问是最安全的写法,例如ctx.blockModel?.resource?.refresh?.()

五、与 ctx.model、ctx.form 的关系

三个入口各司其职,官方推荐用法如下:

需求推荐用法
当前 JS 所在的父区块ctx.blockModel
读写表单字段ctx.form(等价于ctx.blockModel?.form,表单区块下更便捷)
当前执行上下文所在模型ctx.model(JSField 中为字段模型,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?.();

七、注意事项(完整清单)

  1. 空值防御ctx.blockModel独立 JSBlock(无父表单/表格区块)时可能为null,访问其属性前建议使用可选链:ctx.blockModel?.resource?.refresh?.()
  2. 载体差异:在JSField / JSItem / JSColumn中,ctx.blockModel为承载当前字段的表单或表格区块;在JSBlock中,可能为自身或上层区块,取决于实际层级(源码以context?.blockModel === m判断"自身即父区块",见 flowContext.ts)。
  3. 属性存在性resource仅在数据区块下存在;form仅在表单区块下存在,表格区块通常无form

八、源码与测试索引

内容路径
区块基类与ctx.blockModel注入(onInitdefineProperty('blockModel')BlockModel.tsx
数据区块模型:resource与数据加载模式CollectionBlockModel.tsx
区块场景枚举BlockSceneEnumBlockModel.tsx
flow-engine 对ctx.blockModel的读取与自身区块判定flowContext.ts
ctx.blockModel相关行为测试(表单联动、数据范围清理)dataScopeFormValueClear.test.ts
RunJS 表单提交链路测试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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 14:17:43

华为MPR+LTC双流程引擎重构实践

简介:本资源为华为终端市场营销领域MPRLTC流程规划方案的完整PPT汇报材料,面向企业流程优化从业者、销售体系变革设计者、IT与业务协同项目组成员及管理咨询从业者。方案聚焦华为终端从运营商“直销”向公开市场“分销”转型背景下的销售流程重构&#x…

作者头像 李华
网站建设 2026/9/17 14:17:03

集成MEMS表面硅加工:LPCVD多晶硅、牺牲层释放与抗粘附

简介:围绕MEMS表面硅加工技术的PPT课件,面向微电子、微机电系统方向的学生与工程技术人员,用于梳理表面微机械加工的核心工艺脉络。内容覆盖微加工工艺分类、表面微加工与IC工艺的区别,重点讲牺牲层腐蚀原理及二氧化硅、磷硅玻璃、…

作者头像 李华
网站建设 2026/9/17 14:15:56

印刷机机构运动仿真平台:参数化建模与实时动画教学实践

简介:本资源是面向机械设计制造及其自动化专业本科生的《机械原理》课程设计实践材料,聚焦平台印刷机主传动机构的系统化设计与分析。内容覆盖曲柄滑块机构、双曲柄机构、凸轮机构等核心传动单元的运动简图绘制、几何关系推导、参数选择与函数逼近法设计…

作者头像 李华
网站建设 2026/9/17 14:13:22

VMD-SE-Transformer-GRU多变量时序预测MATLAB实战

简介:本资源面向具备一定信号处理与深度学习基础、熟悉MATLAB编程的研发人员、数据科学家与研究生,聚焦多变量时序中非平稳性、多尺度波动与变量耦合等难点。资源为1个docx文档,压缩包约117KB,以项目报告形式系统梳理了基于变分模…

作者头像 李华
网站建设 2026/9/17 14:12:50

基于改进PSO算法的配电网储能优化MATLAB实现

1. 项目概述在电力系统规划与运行中,分布式电源(DG)和储能系统的合理配置是提升电网可靠性和经济性的关键。这个基于改进粒子群算法的MATLAB程序,专门用于解决含分布式电源的配电网中储能系统选址和容量优化问题。作为一名电力系统工程师,我在…

作者头像 李华