news 2026/9/14 12:08:11

lowcode-engine 设置面板「高级」Tab 定制指南:基于 registerMetadataTransducer 的物料元数据管道

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
lowcode-engine 设置面板「高级」Tab 定制指南:基于 registerMetadataTransducer 的物料元数据管道

lowcode-engine 设置面板「高级」Tab 定制指南:基于 registerMetadataTransducer 的物料元数据管道

【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine

本篇指南聚焦 lowcode-engine 设置面板中默认「高级」Tab 的定制方法。默认情况下,组件属性设置面板的「高级」Tab 内容由引擎内置逻辑生成;如需为所有组件批量追加、删除或改写高级配置项,只需注册物料元数据管道函数(Metadata Transducer)即可。读完本文,你将掌握registerMetadataTransducer的签名、level优先级语义、管道函数的数据流,以及添加/删除/改造「高级」Tab 的完整实战写法。

「高级」Tab 从哪来:configure.combined 与内置元数据管道

在 lowcode-engine 的物料元数据协议中,组件的configure字段既可以是一个字段配置数组,也可以是一个包含propscombinedadvanced等分组的对象结构。设置面板最终展示的内容来自转换后的configure.combinedcombined不存在时退化为configure.props),这一点在 ComponentMeta.configure 的 getter 实现 中有明确体现:

get configure(): IPublicTypeFieldConfig[] { const config = this._transformedMetadata?.configure; return config?.combined || config?.props || []; }

「高级」Tab 本质上是combined数组中name === '#advanced'的那一组(Group)字段配置。引擎内置的「高级」Tab 内容即通过一组内置管道函数在物料元数据初始化时注入。这些内置管道函数注册在 ComponentActions 的构造函数 中:

constructor() { this.registerMetadataTransducer(legacyIssues, 2, 'legacy-issues'); // 高优先级:处理历史遗留命名 this.registerMetadataTransducer(componentDefaults, 100, 'component-defaults'); // 默认优先级 }

其中legacyIssues负责将devModelowcode/procode规范化为lowCode/proCodecomponentDefaults则会根据组件名后缀(如.Group.Node.Item)自动推断嵌套规则nestingRule。两个内置管道函数的具体实现在 transducers/index.ts 中可以看到,这也印证了:注册管道函数是引擎官方提供、内置功能同样使用的扩展机制

registerMetadataTransducer:API 签名与执行语义

registerMetadataTransducer属于物料 API(material API 文档),完整签名如下:

registerMetadataTransducer( transducer: IPublicTypeMetadataTransducer, // 管道函数本体 level?: number, // 执行优先级,默认 100 id?: string | undefined // 管道函数标识 ): void;

三个参数的含义与工程约束:

  • transducer(管道函数):接收当前转换中的物料元数据(TransformedComponentMetadata),返回一份新的(或修改后的)元数据。它是纯函数式流水线的处理单元,多个管道按顺序串联执行。
  • level(优先级):数值越小越先执行。在 ComponentActions.registerMetadataTransducer 的实现 中,新注册的管道会按 level 升序插入到已注册管道列表的正确位置:
registerMetadataTransducer(transducer, level = 100, id?) { transducer.level = level; transducer.id = id; const i = this.metadataTransducers.findIndex((item) => item.level != null && item.level > level); if (i < 0) { this.metadataTransducers.push(transducer); } else { this.metadataTransducers.splice(i, 0, transducer); } }

因此内置的legacyIssues(level 2)会先于componentDefaults(level 100)执行,用户注册的管道默认也排在 level 100 之后。如果你想覆盖引擎默认注入的「高级」配置,建议使用大于 100 的 level 值,保证在componentDefaults之后执行——官方"删除高级 Tab"示例使用的就是111

  • id(标识):可选的管道名称,便于在getRegisteredMetadataTransducers()返回的数组中识别管道身份。

管道执行链路:从物料描述到设置面板

物料元数据管道函数在每个组件的物料元数据初始化时执行,执行链路位于 ComponentMeta.transformMetadata:

private transformMetadata(metadta: IPublicTypeComponentMetadata): IPublicTypeTransformedComponentMetadata { const registeredTransducers = this.designer.componentActions.getRegisteredMetadataTransducers(); const result = registeredTransducers.reduce((prevMetadata, current) => { return current(prevMetadata); }, preprocessMetadata(metadta)); // ... 处理 experimental 到 configure.advanced 的兼容迁移 return result as any; }

流程拆解如下:

  1. 预处理preprocessMetadataconfigure为数组的旧写法规整为{ props: [...] }对象结构,缺省时补configure: {}
  2. 管道串联:通过Array.prototype.reduce将已注册的全部管道依次作用在元数据上,前一个管道的返回值是后一个管道的入参;
  3. 兼容迁移experimental字段若存在且无configure.advanced,会以deprecate提示并迁移到configure.advanced
  4. 产出消费:转换后的元数据被ComponentMetaconfiguregetter 消费,最终由设置面板(SettingTopEntry / SettingField)渲染为「属性 / 高级」等多个 Tab。

由此可见,管道函数是在"物料原始描述"与"设置面板 UI"之间的统一改写层,无论增删「高级」Tab、还是全局给每个组件补配置项,都应在这个环节完成。

实战一:给所有组件的「高级」Tab 追加配置项

沿用官方示例,注册一个管道,为每个组件的高级配置面板注入一个「是否渲染」(condition)开关:

import { material } from '@alilc/lowcode-engine'; import { IPublicTypeFieldConfig, TransformedComponentMetadata } from '@alilc/lowcode-types'; function addonCombine(metadata: TransformedComponentMetadata) { const { componentName, configure = {} } = metadata; const advanceGroup = []; const combined: FieldConfig[] = []; advanceGroup.push({ name: getConvertedExtraKey('condition'), title: { type: 'i18n', 'zh-CN': '是否渲染', 'en-US': 'Condition' }, defaultValue: true, setter: [ { componentName: 'BoolSetter' }, { componentName: 'VariableSetter' }, ], extraProps: { display: 'block', }, }); combined.push({ name: '#advanced', title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advanced' }, items: advanceGroup, }); return { ...metadata, configure: { ...configure, combined, }, }; } material.registerMetadataTransducer(addonCombine, 1, 'parse-func');

关键点:

  • 分组命名约定name: '#advanced'是引擎识别「高级」Tab 的约定标识,title提供中英文文案,items是该 Tab 下的字段配置数组;
  • setter 组合['BoolSetter', 'VariableSetter']表示布尔开关 + 变量绑定两种设置器并存,可在属性面板中互相切换;
  • field 的通用配置defaultValueextraProps.display: 'block'等均遵循 FieldConfig 字段配置协议,getConvertedExtraKey用于把condition这类引擎保留键转换为带前缀的合法 prop 名。

实战二:彻底移除「高级」Tab

若业务上不希望展示引擎默认的高级配置,可注册一个过滤管道,把combined中名为#advanced的分组剔除(官方示例中 level 取111,确保在内置componentDefaults之后执行):

import { material } from '@alilc/lowcode-engine'; import { IPublicTypeFieldConfig } from '@alilc/lowcode-types'; material.registerMetadataTransducer((transducer) => { const combined: IPublicTypeFieldConfig[] = []; transducer.configure.combined?.forEach((d) => { if (d.name !== '#advanced') { combined.push(d); } }); return { ...transducer, configure: { ...transducer.configure, combined, }, }; }, 111, 'parse-func');

执行效果:设置面板中将不再渲染「高级」Tab;若只想去掉部分默认项(例如仅移除「是否渲染」),只需把过滤条件改为d.name !== 'condition'并保持分组本身存在即可。

实战三:按组件差异化定制

管道函数入参中带有componentName,可据此针对特定组件做差异化处理。例如:只为Button组件追加自定义高级项,其他组件保持原样:

material.registerMetadataTransducer((metadata) => { if (metadata.componentName !== 'Button') { return metadata; } const combined = metadata.configure.combined ?? []; const advancedIndex = combined.findIndex((d) => d.name === '#advanced'); // 在既有高级分组中追加自定义字段…… return { ...metadata, configure: { ...metadata.configure, combined } }; }, 101, 'button-advanced-addon');

辅助 API 与注意事项

  • 查看已注册管道material.getRegisteredMetadataTransducers()返回全部管道数组,可用于调试或确认自定义管道是否注册成功(material API 文档);
  • 修改已注册管道:目前 API 层面不提供"注销"能力,同一id重复注册不会覆盖旧管道,因此幂等性需要由管道函数自身保证(例如通过metadata.configure.combined中是否已存在某项来判断是否重复注入);
  • 执行时机:管道函数在物料元数据初始化时执行一次,若在运行时调用material.loadIncrementalAssets加载增量资产,可通过 refreshComponentMetasMap 触发模拟器中组件元数据重建;
  • 底层实现文件:管道注册与排序逻辑见 component-actions.ts,元数据转换与消费链路见 component-meta.ts,内置管道实现见 transducers/index.ts。

小结

设置面板的「高级」Tab 并非写死的引擎 UI,而是物料元数据管道函数在初始化阶段注入configure.combined#advanced分组的产物。通过registerMetadataTransducer(transducer, level, id),开发者可以在不改动引擎源码的前提下,对全部或指定组件的属性设置面板做批量增强:追加自定义配置项、删除默认高级项、按组件差异化定制。把握两个核心即可灵活运用:一是管道按level升序执行、默认 100、覆盖内置逻辑请取更大值;二是每个管道都是"输入元数据 → 输出新元数据"的纯函数,务必保持返回结构完整(...metadata展开后再覆盖configure)。

【免费下载链接】lowcode-engineAn enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系项目地址: https://gitcode.com/GitHub_Trending/lo/lowcode-engine

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

Python环境配置与开发入门指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

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

SurfSense 前端 SVG 精度优化实战:用 SVGO 精简图标资源体积

SurfSense 前端 SVG 精度优化实战&#xff1a;用 SVGO 精简图标资源体积 【免费下载链接】SurfSense Open-source NotebookLM alternative. Research the open web with live data(Reddit, YT, IG, TikTok, Indeed, Google Search, Maps etc) through one platform, API or MCP…

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

有线通信标准全解析:从铜缆到光纤,从以太网到工业总线

我入行那会儿&#xff0c;师傅跟我说过一句话&#xff1a;无线是趋势&#xff0c;但有线才是底线。干了十几年通信和嵌入式相关的活儿&#xff0c;这话我越想越觉得对。数据中心里几百G的流量在跑&#xff0c;工厂产线上机械臂在分秒级联动&#xff0c;手术室里超高清内窥镜画面…

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

从零手写MCP Server:协议核心、开发部署与客户端接入全指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华