ARTICLE DETAIL

资讯详情

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

NocoBase 区块扩展开发:从 BlockModel 到 TableBlockModel 的自定义区块实战指南

NocoBase 区块扩展开发:从 BlockModel 到 TableBlockModel 的自定义区块实战指南 NocoBase 区块扩展开发从 BlockModel 到 TableBlockModel 的自定义区块实战指南【免费下载链接】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区块Block是 NocoBase 页面上承载内容的区域——表格、表单、图表、详情等都是一种区块。本指南以 NocoBase 客户端 Flow Engine 的区块模型体系为核心讲解如何通过继承BlockModel系列基类创建自定义区块并通过define()与registerFlow()将其注册到「添加区块」菜单最终交付可直接在界面上拖入使用的自定义区块。读完本文你将掌握四个区块基类的选型逻辑、完整示例代码、区块注册方式以及各基类的底层源码机制。基类选择四个区块基类与继承链路NocoBase 提供了三个区块基类外加一个内置的完整实现根据数据需求选择基类继承关系适用场景BlockModel最基础的区块不需要数据源的展示区块DataBlockModel继承BlockModel需要数据但不绑定 NocoBase 数据表CollectionBlockModel继承DataBlockModel绑定 NocoBase 数据表自动获取数据TableBlockModel继承CollectionBlockModel完整的表格区块自带字段列、操作栏、分页等继承链路是BlockModel→DataBlockModel→CollectionBlockModel→TableBlockModel。选择建议想要一个开箱即用的表格区块直接用TableBlockModel——它自带字段列、操作栏、分页、排序等完整能力是用得最多的基类需要完全自定义渲染方式比如卡片列表、时间线等用CollectionBlockModel自己写renderComponent只是展示静态内容或自定义 UI用BlockModel就够了。DataBlockModel的定位比较特殊——它本身不添加任何新属性或方法类体是空的见 DataBlockModel.tsx。它的作用是分类标识继承DataBlockModel的区块会被归入 UI 上的「数据区块」分组菜单。如果你的区块需要自己管理数据获取逻辑不走 NocoBase 标准的 Collection 绑定可以继承DataBlockModel。比如图表插件的ChartBlockModel就是这样——它用自定义的ChartResource获取数据不需要标准的数据表绑定。大多数场景下你不需要直接用DataBlockModel用CollectionBlockModel或TableBlockModel就够了。认识 BlockModel 基类区块的最小契约BlockModel定义在 BlockModel.tsx 中继承自 Flow Engine 的FlowModel。它是所有区块的契约基类核心机制包括renderComponent()渲染区块 UI 的抽象方法基类默认直接抛错——throw new Error(renderComponent method must be implemented in subclasses of BlockModel)子类必须实现见 BlockModel.tsxrender()把renderComponent()的返回值用observer包装成ObservedRenderComponent后放进BlockItemCard卡片容器中渲染同时检查collectionRequired——当区块声明需要数据表但上下文没有 collection 时渲染BlockDeletePlaceholder占位见 BlockModel.tsxdefine()静态元信息定义label用于「添加区块」菜单中的显示名hide表示不在菜单中直接展示registerFlow()为区块注册可视化配置流程registerFlow({ key, title, steps })中的steps会出现在区块的配置面板中内置cardSettings流基类已经自带「Card settings」配置流包含titleDescription标题与描述、linkageRules联动规则、blockHeight区块高度三个步骤也就是说任何区块都天然支持标题描述、联动规则与高度设置见 BlockModel.tsxbeforeRender事件基类通过FlowModel.registerEvents注册了beforeRender事件支持用条件构建器ConditionBuilder配置触发条件这正是后续示例中registerFlow({ on: beforeRender })得以生效的基础见 BlockModel.tsx。基类还提供了setDecoratorProps()、getModelClassName()、hasActiveFilters()、getDataLoadingMode()等辅助方法供子类在渲染与数据刷新时使用。BlockModel 示例一个支持编辑 HTML 的最简区块原文档附带一段演示视频编辑 HTML 内容并实时渲染对应的完整代码实现如下仓库中的真实示例位于 plugin-simple-block/src/client-v2/models/SimpleBlockModel.tsx// models/SimpleBlockModel.tsx import React from react; import { BlockModel } from nocobase/client-v2; import { tExpr } from nocobase/flow-engine; export class SimpleBlockModel extends BlockModel { renderComponent() { return div dangerouslySetInnerHTML{{ __html: this.props.html }} /; } } SimpleBlockModel.define({ label: tExpr(Simple block), }); SimpleBlockModel.registerFlow({ key: flow1, title: tExpr(Simple Block Flow), on: beforeRender, steps: { editHtml: { title: tExpr(Edit HTML Content), uiSchema: { html: { type: string, title: tExpr(HTML Content), x-decorator: FormItem, x-component: Input.TextArea, }, }, defaultParams: { html: h3This is a simple block/h3 pYou can edit the HTML content./p, }, handler(ctx, params) { ctx.model.props.html params.html; }, }, }, });这个示例覆盖了区块开发的三个步骤renderComponent()— 渲染区块 UI通过this.props读取属性。这里读取的是this.props.html即用户在配置面板中编辑的 HTML 内容define()— 设置区块在「添加区块」菜单里的显示名。label使用tExpr()包装使其支持国际化翻译registerFlow()— 添加可视化配置面板。on: beforeRender表示该配置流在渲染前执行steps.editHtml定义了名为editHtml的配置步骤uiSchema用 schema 描述「HTML Content」输入框Input.TextAreadefaultParams给出默认 HTML 内容handler在用户保存配置时把params.html写回ctx.model.props.html从而触发renderComponent()重新渲染。用户在界面上点击区块的配置按钮即可编辑 HTML实现可视化配置。场景与分组BlockSceneEnum 与「数据区块」菜单BlockSceneEnum定义在 BlockModel.tsx完整枚举如下枚举值类型含义newnew新建记录场景如「Add new」弹窗oneone单条记录详情/表单场景manymany多条记录列表场景selectselect记录选择器场景filterfilter筛选区块场景oam[one, many]单条与多条的组合subFormsubForm子表单场景bulkEditFormbulkEditForm批量编辑表单场景BlockSceneType支持数组形式如oam静态方法_getScene()会把static scene用_.castArray归一化为数组_isScene(scene)则判断区块是否属于某个场景——「添加区块」菜单正是根据场景来决定展示哪些区块的。DataBlockModel虽然是空类体但通过define()声明了分组身份DataBlockModel.define({ hide: true, label: tExpr(Data blocks), async children(ctx) { // 根据 scene 过滤子菜单项 // select 场景只保留支持 select 的区块 // subForm / bulkEditForm 场景各自过滤 // new 场景或带 collectionName 且无 filterByTk 时只保留支持 new 的区块 // 其余场景排除 select/subForm/bulkEditForm 专属区块。 }, });见 DataBlockModel.tsx。BlockModel同样以hide: true, label: tExpr(Other blocks)定义了「其他区块」分组。因此「添加区块」菜单的顶层结构就是数据区块DataBlockModel子孙、其他区块BlockModel子孙等分组。仓库测试 BlockGridModel.selectSceneAddBlock.test.ts 验证了这一机制在select场景下「其他区块」分组只保留JSBlockModel、IframeBlockModel、MarkdownBlockModelActionPanelBlockModel与ReferenceBlockModel会被过滤掉——说明场景过滤逻辑对菜单项的真实影响。CollectionBlockModel 示例绑定数据表的多记录区块如果区块需要绑定 NocoBase 的数据表用CollectionBlockModel。它会自动处理数据获取。仓库中的真实示例位于 plugin-collection-block/src/client/models/ManyRecordBlockModel.tsx// models/ManyRecordBlockModel.tsx import React from react; import { BlockSceneEnum, CollectionBlockModel } from nocobase/client-v2; import { MultiRecordResource } from nocobase/flow-engine; import { tExpr } from nocobase/flow-engine; export class ManyRecordBlockModel extends CollectionBlockModel { // 声明这是一个多条记录的区块 static scene BlockSceneEnum.many; createResource() { return this.context.makeResource(MultiRecordResource); } get resource() { return this.context.resource as MultiRecordResource; } renderComponent() { return ( div h3数据表区块/h3 {/* resource.getData() 获取数据表的数据 */} pre{JSON.stringify(this.resource.getData(), null, 2)}/pre /div ); } } ManyRecordBlockModel.define({ label: tExpr(Many records), });跟BlockModel比CollectionBlockModel多了这些static scene— 声明区块场景。常用值BlockSceneEnum.many多条记录列表、BlockSceneEnum.one单条记录详情/表单完整枚举见上文createResource()— 创建数据资源MultiRecordResource用于获取多条记录。基类的createResource同样是个必须由子类实现的抽象方法抛错要求子类实现见 CollectionBlockModel.tsxthis.resource.getData()— 获取数据表的数据。数据获取的底层机制CollectionBlockModel在onInit时向 Flow 上下文注入了blockModel、actionName、resourceName、dataSource、collection、resource、association等属性见 CollectionBlockModel.tsx其中resource的 getter 会调用子类的createResource创建资源再设置dataSourceKey与resourceName并监听refresh事件同步数据脏版本。因此子类里this.context.resource、this.context.collection、this.context.dataSource都是直接可用的。CollectionBlockModel还注册了三个内置配置流见 CollectionBlockModel.tsxresourceSettingssort: -999置顶collectionCheck步骤在没有 collection 时直接exitAll()退出aclCheck检查访问权限init步骤校验dataSourceKey、collectionName必填并把sourceId、filterByTk这类运行时参数写入 resource——注意代码注释明确说明sourceId/filterByTk是运行时参数必须放在运行时 context 中refreshSettingssort: 10000refresh步骤负责准备筛选区块FilterManager.prepareFiltersForTarget、根据数据加载模式auto/manual决定是否执行resource.refresh()manual模式且无活跃筛选时清空数据不加载dataLoadingModeSettings数据加载模式配置对应getDataLoadingMode()返回的auto | manual。数据表菜单过滤CollectionBlockModel通过两个静态方法控制「添加区块」菜单里数据表的展示filterCollection(collection)— 静态过滤数据表默认实现要求数据表存在filterTargetKey才返回true见 CollectionBlockModel.tsx。子类可以覆盖它来限制只对特定数据表可用isCollectionAvailable(collection)— 结合区块声明的能力capability与数据表能力做交集判断areCapabilitiesSupported只有能力匹配的数据表才会出现在菜单里。此外defineChildren(ctx)会为菜单构建数据源 → 数据表 → 关联记录的子菜单层级包括select/new场景下的「Current collection」「Associated records」「Other collections」等菜单项以及one场景下的「Current record」菜单项见 CollectionBlockModel.tsx。TableBlockModel 示例开箱即用的完整表格区块TableBlockModel继承自CollectionBlockModel是 NocoBase 内置的完整表格区块——自带字段列、操作栏、分页、排序等能力。用户在「添加区块」里选择「Table」用的就是它其define()声明为label: Table, group: Content, searchable: true, sort: 300见 TableBlockModel.tsx。通常来说如果内置的TableBlockModel已经满足需求用户直接在界面上添加就行开发者不需要做任何事。只有当你需要在 TableBlockModel 基础上做定制时才需要继承它——比如覆盖customModelClasses替换内置的操作组或字段列模型通过filterCollection限制只对特定数据表可用注册额外的 Flow 添加自定义配置项。// 示例限制只对 todoItems 数据表可用的表格区块 import { TableBlockModel } from nocobase/client-v2; import type { Collection } from nocobase/flow-engine; import { tExpr } from ../locale; export class TodoBlockModel extends TableBlockModel { static filterCollection(collection: Collection) { return collection.name todoItems; } } TodoBlockModel.define({ label: tExpr(Todo block), });仓库中的真实实现位于 plugin-custom-table-block-resource/src/client-v2/models/TodoBlockModel.tsx。该插件在load()中还向主数据源注册了todoItems数据表含id、title、completed、priority字段见 plugin.tsx从而让「Todo block」只对todoItems数据表出现在添加菜单中。TableBlockModel 的内部能力与可替换点从 TableBlockModel.tsx 源码可以看到它内置的完整能力static scene BlockSceneEnum.many表格区块天然是多条记录场景_defaultCustomModelClasses声明了可替换的子模型映射——CollectionActionGroupModel集合操作组、RecordActionGroupModel记录操作组、TableColumnModel字段列、TableAssociationFieldGroupModel关联字段组列、TableCustomColumnModel自定义列见 TableBlockModel.tsx。子类通过customModelClasses覆盖其中任意一个 keygetModelClassName()会优先返回自定义类、否则回退默认类——这就是文档所说「覆盖customModelClasses替换内置的操作组或字段列模型」的实现位置createResource使用MultiRecordResource并额外添加X-With-ACL-Meta请求头见 TableBlockModel.tsxtableSettings配置流sort: 500见 TableBlockModel.tsx——内置的可视化配置项完整列表配置步骤类型默认值说明quickEditswitchfalse启用行内快速编辑保存后同步到各列enableRowSelectionswitchtrue启用行选择关闭时清空已选行showRowNumbersswitchtrue显示行号pageSizeselect20每页条数可选 5/10/20/50/100/200dataScope复用—数据范围筛选defaultSorting复用—默认排序规则treeTableswitchfalse树形表格仅 tree 模板数据表显示defaultExpandAllRowsswitchfalse默认展开全部行仅 tree 模板tableDensityselectmiddle表格密度 large/middle/smalldragSort/dragSortBy复用—拖拽排序与排序字段refreshDataaction—刷新数据遍历列重新派发beforeRender渲染细节getColumns()通过mapSubModels(columns, ...)收集字段列模型配置模式下追加「添加字段列」按钮列行内快速编辑通过QuickEditFormModel.open弹出表单保存后写回 resource 数据并触发refresh事件分页逻辑根据count元数据在完整分页与简化分页未知总数场景之间切换见 TableBlockModel.tsx。完整的TableBlockModel定制示例含自定义字段、自定义操作的前后端联动插件见 做一个前后端联动的数据管理插件。注册区块在 Plugin 的load()中通过this.flowEngine.registerModelLoaders()注册loader 使用动态import()实现按需懒加载// plugin.tsx import { Plugin } from nocobase/client-v2; export class MyPlugin extends Plugin { async load() { this.flowEngine.registerModelLoaders({ SimpleBlockModel: { loader: () import(./models/SimpleBlockModel), }, ManyRecordBlockModel: { loader: () import(./models/ManyRecordBlockModel), }, }); } }注册完成后在 NocoBase 界面点击「添加区块」就能看到你的自定义区块了。registerModelLoaders是 Flow Engine 提供的模型懒加载注册 API——把区块模型类的加载函数按名称注册进引擎引擎在「添加区块」菜单需要展示或实例化某个模型时才真正加载对应模块。完整示例源码nocobase-example/plugin-simple-block — BlockModel 示例SimpleBlockModelnocobase-example/plugin-collection-block — CollectionBlockModel 示例ManyRecordBlockModelnocobase-example/plugin-custom-table-block-resource — TableBlockModel 定制示例TodoBlockModel含todoItems数据表与客户端注册逻辑相关链接插件实战做一个自定义展示区块 — 从零搭建一个可配置的 BlockModel 区块插件实战做一个前后端联动的数据管理插件 — TableBlockModel 自定义字段 自定义操作的完整示例FlowEngine 概述 — FlowModel 基础用法和 registerFlow字段扩展 — 自定义字段组件操作扩展 — 自定义操作按钮Resource API 速查表 — MultiRecordResource / SingleRecordResource 的完整方法签名FlowDefinition 流定义 — registerFlow 的完整参数和事件类型FlowEngine 完整文档 — 完整参考【免费下载链接】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),仅供参考
返回列表