ExpressionEditor
按模板占位符结构化编辑表达式,支持表达式文本与控件值双向解析。中文惯用名:表达式编辑器。
稳定本期新增已接入
元信息
| 字段 | 值 |
|---|---|
| 规范 ID | component.expression-editor |
| 名称 | ExpressionEditor |
| 二级分类 | 业务组件(business) |
| 用途 | 按模板占位符结构化编辑表达式,支持表达式文本与控件值双向解析 |
| 描述 | 中文惯用名:表达式编辑器。 |
预览
静态结构:根节点为纵向编辑器容器——顶部左侧 label(required 时带 *),右侧按钮随状态切换(display 态出「编辑」,edit 态出「取消 / 确定」,viewOnly / readonly 隐藏);display 态展示可编辑表达式文本(Textarea,实时 emit);edit 态按 valueTemplate 的 ${key} 占位符拆分(正则 /\$\{(\w+)\}/g,未在 valueMapping 定义的占位符保留字面量、同 key 去重)渲染子字段控件——type=select 用 SearchableSelect(>10 条启用搜索)、number 用数字输入、fieldCondition 内嵌 FieldCondition(变更经 conditionToStatement 输出语句串、外部值经 statementToCondition 反向回填,用户编辑后不再被覆盖)、其余回退文本输入;确定时逐项执行 validateMappingValue(required 优先、pattern 正则次之),未通过写入 draftErrors 并阻断,同时经 onValidityChange 上报;viewOnly 态以禁用控件形态只读展示解析值;valueTemplate 为空渲染 null。
DSL 结构
{
"type": "ExpressionEditor",
"props": {
"label": "周期表达式",
"required": true,
"value": "${state.formula}",
"valueTemplate": "return ft.period({{start}}, {{end}})",
"valueMapping": {
"start": {
"label": "起始周期",
"type": "number",
"default": 1,
"required": true
},
"end": {
"label": "结束周期",
"type": "number",
"default": 12,
"required": true
}
}
},
"events": {
"onChange": {
"action": "setState",
"params": {
"formula": "${event}"
}
}
}
}何时用
何时使用
- 表达式模板含动态占位符(如
return ft.period(${start}, ${end})),需要以表单控件结构化编辑占位参数。 - 同一表达式既要结构化编辑、也要直接编辑表达式文本(display / edit 两步编辑)。
- 需要表达式字符串与控件值双向同步:外部赋值(AI 填充、表单回显)反向解析回控件。
何时不用
- 自由代码 / 脚本输入(语法高亮、函数联想):使用 ScriptEditor。
- 单行「字段 + 操作符 + 值」条件编辑:使用 FieldCondition。
- 无模板、无占位符的普通文本输入:使用 Input / Textarea。
变体
| 变体 | 视觉形态 | 适用场景 |
|---|---|---|
| display / edit 两步编辑 | 表达式文本区 ↔ 结构化子字段表单 | 既有表达式文本直编灵活性,又有模板参数控件校验 |
| viewOnly 只读展示 | 解析值以禁用控件形态呈现,无操作按钮 | 详情页复用同一结构回显 |
| mapping 控件 type 分发 | select / number / fieldCondition / 文本输入 | 占位参数按配置渲染对应控件 |
| readonly 只读文本 | 表达式文本只读、隐藏编辑入口 | 仅允许直接编辑表达式文本的场景 |
API 属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
id | string | — | 根节点 id |
value | string | — | 受控值(组合后的表达式字符串) |
onChange | (value: string) => void | — | 表达式变更回调(display 态实时 emit) |
valueTemplate | string | — | 表单值模板(如 "return ft.period(${a}, ${b})");空串时渲染 null。占位符支持 ${key} 与 {{key}} 两种写法,DSL props 内联书写时须用 {{key}}(${ 会被 DSL 表达式引擎提前求值) |
valueMapping | Record<string, ExpressionMappingItem> | — | 模板占位符(${key} / {{key}})到控件配置的映射;未映射占位符保留字面量 |
optionSources | Record<string, unknown> | — | 页面级候选源集合;仅静态 { options } 条目生效,远程 { request } 条目按空候选渲染 |
label | `string | null` | — |
required | boolean | false | 必填标记(label 后显示 *) |
readonly | boolean | false | 表达式文本只读(隐藏编辑按钮) |
viewOnly | boolean | false | 只读展示模式:控件禁用、隐藏编辑 / 确定 / 取消按钮 |
className | string | — | 根容器类名 |
onValidityChange | (invalid: boolean) => void | — | 编辑态草稿存在未通过校验项时上报 true,供外层表单提交前阻断 |
使用规范
- 占位符 key 与 valueMapping 一一对应:模板中出现的 ${key} 都应在 mapping 中定义,否则保留字面量造成表达式不完整。
- 校验写在 mapping 的 validation(pattern 正则 + message),编辑态逐项校验,不通过阻断「确定」。
- fieldCondition 类型以表达式字符串双向转换(conditionToStatement / statementToCondition),适合条件参数位。
- 远程 optionSource({ request })本期不支持、按空候选渲染;需要远程数据由页面先取数转静态 options。
- 外部程序化赋值会反向解析回控件,赋值格式需与模板一致;解析失败保持现状。
正例
- ✓ 周期表达式:valueTemplate "return ft.period(${start}, ${end})",start / end 映射为 number 控件。
- ✓ 带条件的表达式:${filter} 映射 fieldCondition 类型,确定后组合出含条件语句的表达式串。
- ✓ 详情页回显:viewOnly + 相同 valueMapping,复用编辑态的结构化控件形态。
反例
- ✕ 把自由代码(Python 脚本)放进表达式模板(应使用 ScriptEditor)。
- ✕ 只给 valueTemplate 不给 valueMapping:占位符全部保留字面量,编辑态无控件可填。
- ✕ 对远程 optionSource 期望直接生效(本期按空候选渲染,需页面预取)。
Design Token 映射
不适用:组件 tokenRefs 为空:样式 Token 数据尚未接入,三层映射(Primitive → Semantic → Component)待样式 Token 接入后回填。