重要: 这篇文章不是表单联动实现的最佳方案,只是个人对联动的一些想法,欢迎探讨
表单联动是表单可视化配置的难点之一,如何以最少的代码实现尽可能多的联动功能感觉是一个悖论。
表单联动实现大体分为三种方式:
开发一个可视化配置联动的方案需要考虑三个成本:
本质上并没有一个最佳的方案,本文只是针对固定表单联动场景,提高搭建效率的探索和纯配置实现尽可能多的联动功能的思考
在设计配置协议前,我们需要了解常见的表单联动场景
对上述几种场景进行分析,发现大部分的联动代码逻辑都可以通过编写if语句实现。
if(条件A){执行B}
复制代码
条件A
针对不同的数据类型,梳理常见的判断表达式以及对应类型的比较操作符
以下是常见的数据类型对应的比较操作符
// nubmer 类型支持的操作符
type NumberOperator = '>=' | '<=' | '<' | '>' | '===' | '!=='
// string 类型支持的操作符
type StringOperator = '===' | '!==' | 'includes' | '-includes'
// boolean 类型支持的操作符
type BooleanOperator = 'true' | 'false'
// object 类型支持的操作符
type ObjectOperator = 'in' | '-in'
// array 类型支持的操作符
type ArrayOperator = 'includes' | '-includes'
复制代码
我们需要获取表单A的值,这个值对应的可能是表单数据(data)、表单的ui数据(uiSchema)、校验数据(dataSchema)。
现在有一个如下的get函数去获取表单的数据
//获取表单A的数据
get(A).data
//获取表单A的ui数据
get(A).uiSchema
//获取表单A的校验数据
get(A).dataSchema
复制代码
最终,条件A可以用下面代码实现
//如果表单A是string类型,并且为1时,执行B
if(get(A).data === '1'){执行B}
复制代码
执行B
条件A满足的时候,我们需要执行B。
在表单联动中,执行B的语句通常是需要设置表单B的数据、ui数据、校验数据
现有一个set函数可以设置表单B的数据
//设置表单B的数据
set(B,'data',value)
//设置表单的ui数据
set(B,'uiSchema',value)
//设置表单的校验数据
set(B,'dataSchema',value)
复制代码
最终,整个语句用下面代码实现
//如果表单A是string类型,并且为1时,设置表单B的值为2
if(get(A).data === '1'){set(B,'data',2)}
复制代码
联动的纯配置化,是需要一个协议去描述上面的if逻辑。并通过一定的转换逻辑(比如:new Function
)将配置转换为代码。
{//联动协议版本version:string//联动协议触发时机trigger:{//全局监听event:'globalChange'}//监听后执行的动作actions:[{//if语句type:'controlFlow'//if条件 (条件A)condintion:[{/*** 表单A的值* 格式:"fieldKey getType property" "fieldKey getType"* fieldkey: 需要获取的表单的fieldkey * getType: 对应get的属性 data|uiSchema|dataSchema* property: 可选 获取属性(用于处理对象)*/fieldKey1:stringoperator:string//被比较值value2:unknown//可能存在多个条件 条件之间的关系 或/且logicOperator:'||'}]//if条件触发的动作(执行Beffect:[{//设置表单数据type:'set',/*** 格式:"fieldKey setType property" "fieldKey setType"* fieldkey: 需要获取的表单的fieldkey* setType: data|uiSchema|dataSchema* property: 可选 获取属性*/fieldKey:string,value:unknown}]}]
}
复制代码
协议定制的时候,需要考虑后续协议的扩展性。
trigger.event
判断参考outlook的邮件规则,最终设计如下
是否有必要支持复杂联动的配置?
复杂联动的配置本质上是对js的语法配置化,对于平台新手用户来说,可能并不了解代码的底层实现,配置成本巨高。而对于开发来说,可能复杂的配置还没有手写几行联动代码更快。
因此联动配置化需要固定的表单业务场景,复杂联动的配置化并不适合。在开发联动配置化前需要梳理当前业务域、支持域。
是否需要一键设置反转? 比如:表单A选中某个值时,表单B隐藏。
开启自动反转,则表单A未选中某个值时,表单B都是展示的
是否需要开启动作触发时机和次数(生命周期概念)
比如:表单A选中某个值时,表单B值为1
表单B的值后续是否可以更改?可以更改,则这个联动是一次性的。不可以更改则是永久的
如何降低联动配置成本
现在的交互设计有理解成本。对于不了解平台的新手,搭建仍然一脸懵。
是否可以通过两次表单的JSON对比,自动生成联动逻辑