京东低代码平台:水滴表单联动可视化配置的实现与思考
创始人
2024-02-27 17:41:38
0

TL;DR

  • drip-form在0.9.0的alpha版支持了可视化配置联动的功能(仍在测试中)
  • drip-form通过协议到代码的转换,尽可能降低常见联动配置的开发成本
  • 探讨:JSON diff动态生成常见联动和校验
  • drip form的后续更新:v0.9.0是v0最后一个版本,后续v0以维护为主并更新v0的文档。v1规划中。
  • 联动或表单有更好的想法,欢迎讨论

前言

重要: 这篇文章不是表单联动实现的最佳方案,只是个人对联动的一些想法,欢迎探讨

表单联动是表单可视化配置的难点之一,如何以最少的代码实现尽可能多的联动功能感觉是一个悖论。

  • 联动功能多,代码量会增加
    我们可以对联动到代码的这层去做转化配置逻辑,减少代码的开发工作量。
  • 联动协议转换联动代码 ,降低了代码编写工作,却带来了新的可视化平台配置上手成本和适配成本

表单联动的实现方式

表单联动实现大体分为三种方式:

  • 纯代码开发
  • 联动协议配置化
  • 部分联动配置化、复杂联动代码开发

开发一个可视化配置联动的方案需要考虑三个成本:

  • 不使用可视化配置联动的代码编写成本、
  • 使用可视化配置表单联动带来的协议理解和配置成本
  • 使用低代码平台的理解成本

本质上并没有一个最佳的方案,本文只是针对固定表单联动场景,提高搭建效率的探索和纯配置实现尽可能多的联动功能的思考

联动常见场景

在设计配置协议前,我们需要了解常见的表单联动场景

  • 表单A控制表单B的数据
  • 表单A控制表单B的样式
    • 表单A控制表单B的展示隐藏
  • 表单A控制表单B的校验
    还有更复杂的联动可能还涉及表单的数据处理和转换逻辑,在涉及到复杂逻辑的时候,纯配置去搭建的联动的成本,可能没有配置+代码或纯代码实现来的快。所以这里不过多讨论

方案设计

实现分析

对上述几种场景进行分析,发现大部分的联动代码逻辑都可以通过编写if语句实现。

if(条件A){执行B}
复制代码

条件A

针对不同的数据类型,梳理常见的判断表达式以及对应类型的比较操作符

  • 表单A 是string类型,且为某个值时
  • 表单A 是number类型,大于某个值时
  • 表单A 是boolean类型,为真时
  • 表单A 是对象类型,包括某个属性时
  • 表单A 是数组类型,包括某个值时
    从上面例子判断表达式的组成:表单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}]}]
}
复制代码

协议定制的时候,需要考虑后续协议的扩展性。

  • 可能会添加新的逻辑判断语句支持(比如else语句、switch case语句等)
    action中添加type判断当前语句
  • 可能存在嵌套语句(比如if的嵌套,子逻辑等)
    语句中的effect添加type判断语句类型
  • 联动的触发时机(比如组件加载,组件变动,依赖变动等)
    添加trigger.event判断

交互设计

参考outlook的邮件规则,最终设计如下

  • 条件
    判断的条件可能存在多个,所以使用或或者且按钮添加更多的条件。
  • 结果
    条件成立,可能执行多个动作。可以使用新增动作添加更多的触发场景
  • if语句或其他语句可能存在多个
    使用新增条件添加更多的联动逻辑

目前方案和思考

联动二期规划

  • 目前联动一期 alpha版并没有实现获取ui配置和设置ui数据和校验数据
    二期需要支持配置ui配置和校验配置
    比如:选中表单A,设置表单B的任何样式,设置表单B的任何校验信息
  • 支持自增模式下嵌套内容的配置

思考

  • 是否有必要支持复杂联动的配置?
    复杂联动的配置本质上是对js的语法配置化,对于平台新手用户来说,可能并不了解代码的底层实现,配置成本巨高。而对于开发来说,可能复杂的配置还没有手写几行联动代码更快。

    因此联动配置化需要固定的表单业务场景,复杂联动的配置化并不适合。在开发联动配置化前需要梳理当前业务域、支持域。

  • 是否需要一键设置反转? 比如:表单A选中某个值时,表单B隐藏。
    开启自动反转,则表单A未选中某个值时,表单B都是展示的

  • 是否需要开启动作触发时机和次数(生命周期概念)
    比如:表单A选中某个值时,表单B值为1
    表单B的值后续是否可以更改?可以更改,则这个联动是一次性的。不可以更改则是永久的

  • 如何降低联动配置成本
    现在的交互设计有理解成本。对于不了解平台的新手,搭建仍然一脸懵。

    是否可以通过两次表单的JSON对比,自动生成联动逻辑

    1. 先拖拽没有触发联动时的表单样式
    2. 配置触发联动之后的表单样式
    3. 两次配置的JSON自动比对,自动生成联动语句
    4. 生成的联动信息提示用户确认

相关内容

热门资讯

修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
【前端】‘??‘与‘||‘有什... 0 问题 经常写const data = res.data.a ?? ''或者const d...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
牛客计算器的改良(Python... 文章目录1.题目描述2.输入描述:3.输出描述:4.示例15.分析6.代码7.结语 链接࿱...
正大杯|市调大赛|2023备赛... 关键信息 同时随着精细化养宠趋势的深入,宠物消费类目日渐丰富。 本报告通过 Niuco...
QGIS下载在线地图(Goog... 前言 国内外有很多在线地图下载软件,但功能单一,基本上只能下载数据&#x...