NocoBase RunJS 深度解析:ctx.collection 数据表实例的元数据访问、主键操作与字段联动实践

NocoBase RunJS 深度解析:ctx.collection 数据表实例的元数据访问、主键操作与字段联动实践 NocoBase RunJS 深度解析ctx.collection 数据表实例的元数据访问、主键操作与字段联动实践【免费下载链接】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/nocobasectx.collection是 NocoBase RunJS 运行时中最核心的上下文属性之一它指向当前 JS 执行上下文关联的数据表Collection实例让开发者无需硬编码表名就能在运行时动态读取数据表的名称、字段列表、主键filterTargetKey、数据源归属与模板类型等元数据。本文基于 官方 ctx.collection 文档结合 NocoBase 仓库中 RunJS 上下文的实际实现完整讲解其适用场景、属性方法清单、与ctx.collectionField/ctx.blockModel的关系以及三个可直接复制的实战示例打开弹窗传filterByTk、遍历字段做必填校验、获取关联字段构建子表格读完即可在自己的 JS 区块 / JS 字段中正确使用这一对象。一、它是什么上下文关联的数据表实例在 NocoBase 中界面区块和字段都建立在数据表Collection之上。当你在 JS 区块JSBlock、JS 字段JSField、表格列JSColumn等场景中编写 RunJS 代码时运行时会把当前上下文绑定的 Collection 实例注入为ctx.collection。它的典型来源是ctx.blockModel.collection父区块绑定的数据表或ctx.collectionField?.collection当前字段所属的数据表。从源码结构看RunJS 上下文的定义位于 flow-engine 包的 runjs-context 目录中例如 JSFieldRunJSContext.ts 与 JSColumnRunJSContext.ts 都显式声明了collection属性并注明其为集合定义元数据只读描述字段所属集合的 Schema。也就是说ctx.collection是一份只读的元数据视图——适合读取结构信息而不是用来直接执行数据库增删改那属于ctx.resource/ API 的范畴。// 类型定义 collection: Collection | null | undefined;需要特别注意空值在数据区块、表单区块、表格区块等绑定数据表的场景下它通常可用但独立 JSBlock 若未绑定数据表ctx.collection可能为null或undefined使用前建议做空值判断下文示例均采用?.访问。二、适用场景速查场景说明JSBlock区块绑定的数据表可访问name、getFields、filterTargetKey等JSField / JSItem / JSColumn当前字段所属数据表或父区块数据表用于获取字段列表、主键等表格列 / 详情区块根据数据表结构渲染、打开弹窗时传入filterByTk等一个容易踩坑的点在子表格、关联字段等场景中ctx.collection可能指向的是关联目标数据表子表而不是父区块绑定的数据表此时它与ctx.blockModel.collection并不相同。三、常用属性详解属性类型说明namestring数据表名称如users、orders常用于动态拼接 API 资源名titlestring数据表标题含国际化filterTargetKeystring \| string[]主键字段名用于filterByTk、getFilterByTKdataSourceKeystring数据源 key如main可据此判断数据表属于主数据源还是外部数据源dataSourceDataSource所属数据源实例templatestring数据表模板如general、file、tree可用于区分普通表、文件表、树形表titleableFieldsCollectionField[]可作为标题展示的字段列表titleCollectionFieldCollectionField标题字段实例这些属性在动态场景下尤其有用。例如借助name可以写出与表名解耦的代码// 用数据表名称动态请求资源避免硬编码 const res await ctx.resource[ctx.collection.name].get({ filterByTk: ctx.record?.[ctx.collection.filterTargetKey], });借助template可以针对不同形态的表采取不同渲染策略如树形表与普通表借助titleableFields/titleCollectionField可以动态决定记录标题用哪个字段展示。四、常用方法详解方法说明getFields(): CollectionField[]获取全部字段含继承用于遍历字段做校验、联动、渲染getField(name: string): CollectionField \| undefined按字段名获取单个字段getFieldByPath(path: string): CollectionField \| undefined按路径获取字段支持关联如user.namegetAssociationFields(types?): CollectionField[]获取关联字段types可为[one]、[many]等getFilterByTK(record): any从记录中提取主键值用于 API 的filterByTk几点关键行为getFields()的继承合并规则它会合并继承数据表的字段且自身字段覆盖同名的继承字段因此拿到的字段列表就是当前数据表最终生效的完整结构。getFilterByTK(record)是filterTargetKey的配套方法等价于从一条记录中取出主键值在需要批量构造filterByTk参数时比手动取字段更稳。getFieldByPath支持关联路径如user.name适合需要跨表读取字段定义的联动逻辑。五、与 ctx.collectionField、ctx.blockModel 的关系三者经常配合使用按想要什么选择正确的入口需求推荐用法当前上下文关联的数据表ctx.collection等价于ctx.blockModel?.collection或ctx.collectionField?.collection当前字段的数据表定义ctx.collectionField?.collection字段所属数据表关联目标数据表ctx.collectionField?.targetCollection关联字段的目标数据表也就是说在普通表单 / 表格中ctx.collection通常就是区块绑定的数据表而在子表格等嵌套场景中它更可能下沉为当前字段所在的那张表。当需要区分父表和当前表时优先显式使用ctx.blockModel.collection与ctx.collectionField?.targetCollection语义更清晰。相关文档可继续阅读 ctx.collectionField、ctx.blockModel、ctx.model。六、实战示例6.1 获取主键并打开弹窗打开记录详情 / 编辑弹窗时filterByTk参数需要的是主键值。用filterTargetKey取主键字段名回退id可以兼容自定义主键的表。仓库中表格单元格打开弹窗的场景片段cell-open-dialog.snippet.ts也是围绕这一模式组织的const primaryKey ctx.collection?.filterTargetKey ?? id; await ctx.openView(popupUid, { mode: dialog, params: { filterByTk: ctx.record?.[primaryKey], record: ctx.record, }, });6.2 遍历字段做必填校验或联动利用getFields()拿到完整字段列表再结合ctx.form逐字段取当前值即可实现不写死字段名的动态必填校验const fields ctx.collection?.getFields() ?? []; const requiredFields fields.filter((f) f.options?.required); for (const f of requiredFields) { const v ctx.form?.getFieldValue(f.name); if (v null || v ) { ctx.message.warning(${f.title} 为必填); return; } }同样的遍历模式也可以用来做字段联动例如根据f.options中的配置判断某字段是否应禁用。6.3 获取关联字段构建子表格getAssociationFields(types)支持按关联类型过滤传入[many]可只拿到一对多关联字段用于自动发现这张表有哪些子表可挂载const oneToMany ctx.collection?.getAssociationFields([many]) ?? []; // 用于构建子表格、关联资源等七、注意事项filterTargetKey是数据表的主键字段名部分数据表可能为string[]复合主键未配置时常用id作为回退。在子表格、关联字段等场景ctx.collection可能指向关联目标数据表与ctx.blockModel.collection不同注意区分当前表与父表。getFields()会合并继承数据表的字段自身字段覆盖同名继承字段。ctx.collection为只读的 Schema 元数据视图且独立 JSBlock 未绑表时可能为null建议统一使用?.与回退值访问。八、小结ctx.collection是 NocoBase RunJS 中让代码认识数据表结构的入口name/filterTargetKey/template等属性解决这是哪张表、主键是谁getFields/getFieldByPath/getAssociationFields等方法解决它有哪些字段、如何遍历联动。配合ctx.form、ctx.resource、ctx.openView等上下文能力即可写出与具体表名解耦、可复用于多张数据表的通用 JS 逻辑。其定义可追溯至 JSFieldRunJSContext.ts 等 runjs-context 上下文实现相关行为亦有 flow-engine 包的 RunJS 上下文测试如 runjsContext.test.ts覆盖。【免费下载链接】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),仅供参考