我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

NocoBase 字段扩展开发实战:基于 FieldModel / ClickableFieldModel 自定义字段渲染与字段接口绑定

NocoBase 字段扩展开发实战:基于 FieldModel / ClickableFieldModel 自定义字段渲染与字段接口绑定 NocoBase 字段扩展开发实战基于 FieldModel / ClickableFieldModel 自定义字段渲染与字段接口绑定【免费下载链接】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 中表格与表单里的每个字段列都是由**字段组件Field**完成展示和编辑的。当内置字段无法满足定制需求时你可以通过继承FieldModel相关基类自定义字段的渲染方式——既可以用特殊格式展示数据也可以用自定义组件来编辑。本文以 FlowEngine 的字段扩展机制为主线结合仓库内nocobase-example/plugin-field-simple示例插件与client-v2核心源码带你从零掌握自定义字段组件的完整开发链路renderComponent渲染重写、context.record行数据读取、bindModelToInterface字段接口绑定、registerModelLoaders按需注册以及点击打开click-to-open等交互能力的底层原理。字段扩展机制概述在 NocoBase 的 FlowEngine 架构中页面上的区块、字段、操作都是通过FlowModel 模型类来描述的字段组件则是这一体系中的「字段子模型」。字段扩展的入口类是FieldModel它继承自FlowModel并针对字段场景做了一层关键适配字段实例的实际目标类可以通过stepParams.fieldBinding.use动态指定——如果存在显式的fieldBinding.use则优先返回它否则回退到自身。这一点在 FieldModel.tsx 的resolveUse静态方法中有明确实现正是它支撑了「同一个字段接口interface在不同场景下切换不同字段模型」的能力。从源码结构看client-v2内置了大量字段模型全部位于 fields 目录 下例如展示类DisplayTextFieldModel、DisplayNumberFieldModel、DisplayPercentFieldModel、DisplayDateTimeFieldModel、DisplayEnumFieldModel、DisplayCheckboxFieldModel、DisplayPasswordFieldModel等统一继承自ClickableFieldModel编辑类InputFieldModel、TextareaFieldModel、NumberFieldModel、SelectFieldModel、CheckboxFieldModel、RadioGroupFieldModel、DateTimeFieldModel、JsonFieldModel、IconFieldModel、ColorFieldModel等关联类AssociationFieldModel下的RecordPickerFieldModel、SubTableFieldModel、CascadeSelectFieldModel、RecordSelectFieldModel等。自定义字段扩展的思路就是围绕这些内置模型所共享的基类FieldModel→ClickableFieldModel做继承与重写。本文的示例插件位于仓库的 packages/plugins/nocobase-example/plugin-field-simple 目录是官方提供的完整可运行示例。示例自定义展示字段下面这个示例创建一个简单的展示字段——在字段值两侧加上方括号[]// src/client-v2/models/DisplaySimpleFieldModel.tsx import React from react; import { ClickableFieldModel } from nocobase/client-v2; import { DisplayItemModel } from nocobase/flow-engine; import { tExpr } from ../locale; export class DisplaySimpleFieldModel extends ClickableFieldModel { public renderComponent(value: string) { // this.context.record 可以拿到当前行的完整记录 console.log(当前记录, this.context.record); console.log(当前记录 index, this.context.recordIndex); return span[{value}]/span; } } // 设置在「字段组件」下拉菜单里的显示名 DisplaySimpleFieldModel.define({ label: tExpr(Simple field), }); // 绑定到 input 类型的字段接口 DisplayItemModel.bindModelToInterface(DisplaySimpleFieldModel, [input]);仓库中该示例的完整实现见 DisplaySimpleFieldModel.tsx其中tExpr(Simple field)是延迟翻译翻译 key 需要在插件的语言文件中补充见下文「多语言配置」小节。代码中的几个关键点renderComponent(value)— 接收当前字段的值作为参数返回渲染的 JSX。它是自定义渲染的核心钩子this.context.record— 获取当前行的完整数据记录this.context.recordIndex— 获取当前行的索引ClickableFieldModel— 继承自FieldModel带有点击交互能力如点击打开记录define({ label })— 设置在「字段组件」下拉菜单里的显示名不加的话会直接显示类名DisplayItemModel.bindModelToInterface()— 把字段模型绑定到指定的字段接口类型比如input表示单行文本字段这样在对应类型的字段上就能选择这个展示组件。renderComponent 的调用链自定义renderComponent会被基类的统一渲染流程调用。查看 ClickableFieldModel.tsx 可以看到基类定义了renderComponent(value, wrap?)的默认实现直接返回原值子类重写它来改变展示renderInDisplayStyle(value, record?, isToMany?, wrap?)负责按displayStyletag/text两种展示模式包装渲染结果tag模式渲染为antd的Tagtext模式渲染为span并处理clickToOpen、overflowMode超长省略、titleField关联字段的标题字段等展示属性render()方法作为基类的统一渲染入口处理titleField场景下的多条记录拼接用,分隔、树形数据tree template的层级路径a / b / c拼接以及无titleField时的纯文本渲染最终统一包一层EllipsisWithTooltip支持省略号提示。也就是说自定义字段只需重写renderComponent返回 JSX其余展示细节标签/文本模式、省略、点击打开由基类兜底完成。基类渲染逻辑的测试覆盖在 ClickableFieldModel.test.ts其中通过构造belongsToMany类型的roles字段验证了关联字段点击打开时的dispatchEvent事件负载filterByTk、collectionName、associationName、sourceId等可作为理解点击交互行为与关联字段处理逻辑的参考。注册字段自定义字段模型必须注册到 FlowEngine 才能被按需加载。在 Plugin 的load()中用registerModelLoaders注册// src/client-v2/plugin.tsx import { Plugin } from nocobase/client-v2; export class PluginFieldSimpleClient extends Plugin { async load() { this.flowEngine.registerModelLoaders({ DisplaySimpleFieldModel: { loader: () import(./models/DisplaySimpleFieldModel), }, }); } } export default PluginFieldSimpleClient;仓库中的实际实现见 plugin.tsx。registerModelLoaders的底层实现位于 flowEngine.ts它接收一个「模型名 →{ loader, extends }」的映射表loader是动态 import 函数实现代码分割与按需加载extends用于声明父类供getSubclassesOfAsync做异步子类发现可传字符串、模型类或二者的数组。同名 loader 重复注册时会打印警告并覆盖注册后内部会重置预加载缓存确保下次解析能拿到最新条目。注册完成后在表格区块里找到一个对应类型的字段列比如上面示例绑定了input对应单行文本字段点击列的配置按钮在「字段组件」下拉菜单中就能切换到这个自定义展示组件。字段接口绑定的底层原理DisplayItemModel.bindModelToInterface(DisplaySimpleFieldModel, [input])是「字段模型 ↔ 字段接口」的绑定入口其静态实现位于 CollectionFieldModel.tsx支持传单个接口名或接口名数组数组会逐个递归绑定每个绑定条目包含modelName、isDefault是否默认绑定、defaultProps默认属性可为函数、when绑定生效条件默认恒为 true、order排序等字段绑定结果存入当前类的currentBindings映射以 interface 名为 keybindingsgetter 还会沿类继承链向上收集父类的绑定。在实际解析时getDefaultBindingByField会根据字段的interface名在绑定映射中查找优先挑选isDefault且模型类已注册、when条件通过的绑定存在多个默认绑定时会优先选择带自定义when的那一个然后回退到默认when的绑定严格模式useStrict下找不到则返回 null。这套机制保证了「一个字段接口类型可以挂多个候选字段组件并可设置默认项」。bindModelToInterface的行为在 CollectionFieldModel.test.ts 中有完整测试覆盖包括数组接口名绑定、when条件过滤、isDefault冲突处理、多模型同名接口绑定等场景可作为深入理解绑定规则的测试参考。多语言配置字段模型中用tExpr(Simple field)声明的显示名需要在插件的语言文件中补充翻译// src/locale/zh-CN.json { Simple field: 简单字段 }// src/locale/en-US.json { Simple field: Simple field }:::warning 注意 初次添加语言文件需要重启应用才能生效。 :::仓库示例的翻译文件位于 packages/plugins/nocobase-example/plugin-field-simple/src/locale。tExpr()是延迟翻译函数会在渲染时才解析翻译避免在模块加载阶段依赖 locale 上下文。从零搭建完整开发步骤完整的实战演练请参阅 做一个自定义字段组件这里给出从零搭建的步骤概览创建插件骨架在仓库根目录执行yarn pm create my-project/plugin-field-simple详细说明见编写第一个插件随后启动开发模式——nb init创建的项目在项目根目录下执行nb source devclone 的源码仓库在源码根目录下执行yarn dev即可获得热更新。创建字段模型新建src/client-v2/models/DisplaySimpleFieldModel.tsx继承ClickableFieldModel重写renderComponent用define({ label })设置下拉菜单显示名用bindModelToInterface绑定到input接口。添加多语言文件在src/locale/下为tExpr()用到的 key 补齐各语言翻译。在插件中注册在src/client-v2/plugin.tsx的load()里用registerModelLoaders注册模型 loader。启用插件执行yarn pm enable my-project/plugin-field-simple仓库自带示例插件为yarn pm enable nocobase-example/plugin-field-simple。启用后在表格区块里找到单行文本字段的列点击列的配置按钮在「字段组件」下拉菜单中切换到自定义展示组件即可看到该列值以[value]格式显示。点击打开能力与内置设置项ClickableFieldModel相对FieldModel的核心增量是点击交互与展示设置项。其onClick方法ClickableFieldModel.tsx实现了三类点击行为关联字段如 m2m根据filterByTk、目标集合、关联路径等构造事件负载支持associationNamesourceId的关联资源定位m2m 场景下特别使用目标集合的filterTargetKey作为filterByTk关联路径下的属性字段通过associationPathName定位父级关联字段复用其sourceKey/targetKey/foreignKey计算资源定位参数普通字段使用当前资源的sourceId与集合的getFilterByTK计算结果作为filterByTk。点击事件统一通过dispatchEvent(click, payload, { debounce: true })派发附带防抖。此外ClickableFieldModel通过registerFlow注册了名为displayFieldSettings的设置流ClickableFieldModel.tsx向字段配置面板注入以下设置步骤设置项类型说明displayStyleselect展示模式可选Tag/Text默认textselect、multipleSelect、radioGroup、checkboxGroup等接口类型下自动隐藏overflowModeuse超长内容溢出模式如省略号ellipsisclickToOpenswitch是否启用点击打开默认值取决于ctx.disableFieldClickToOpen禁用时强制 false与字段是否为关联字段关联字段默认 true设置保存后通过applyClickToOpenSetting应用属性并刷新运行时含父模型的重渲染同时ClickableFieldModel还注册了openViewFlow流来承载打开视图的具体行为。更多源码参考字段模型基类 FieldModel — 字段子模型入口类与fieldBinding.use动态解析ClickableFieldModel — 可点击字段基类统一渲染、点击打开、内置设置项内置字段模型目录 — 展示类 / 编辑类 / 关联类字段模型的完整实现CollectionFieldModel 绑定实现 —bindModelToInterface与getDefaultBindingByField源码registerModelLoaders 实现 — 模型按需加载注册的底层逻辑自定义字段实战示例 — 从零搭建自定义字段组件插件的分步教程示例插件完整源码 —client-v2与client双版本实现相关阅读插件实战做一个前后端联动的数据管理插件 — 自定义字段在完整插件中的实际应用FlowEngine 概述 — FlowModel 基础用法区块扩展 — 自定义区块操作扩展 — 自定义操作按钮FlowDefinition 流定义 —registerFlow的完整参数和事件类型FlowEngine 完整文档 — FlowModel、Flow、Context 的完整参考【免费下载链接】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),仅供参考
返回列表