技术中台之DevOps动态表单体系构建

发布于 2021-01-19 14:05

表单是前端开发常用的数据采集工具,随着技术发展,一个完善应用系统包含的功能越来越复杂,所需要的表单也越来越多。这些表单大同小异,使用的都是常用的输入框、下拉选择框等表单控件,各个表单之间的差异无非是使用控件的种类数目和与控件相对应的字段名称,对于表单的渲染和数据收集逻辑,都有极强的逻辑可以寻找,因此动态表单应运而生。

顾名思义,动态表单就是根据表单配置动态的渲染表单,实现需求,而不是一段段写死的大同小异的代码。动态表单的产生,大大的提升了开发效率,开发人员不用继续埋头在一堆单调的表单代码中和需求文件作斗争了。但是如何实现一个高效易用动态表单,也是一个不小的难题,今天就以普元技术中台DevOps的动态表单开发历程为例,为大家介绍DevOps项目中动态表单的发展史。

目录:

1.初版动态表单

2.问题和新需求

3.动态表单进阶

一、初版动态表单

最初的DevOps平台并没有关于动态表单的需求,在开发过程中,由于CICD部分种类纷繁的任务类型配置需要大量的表单与之一一对应,想要人工写完这些表单无疑要耗费很多的时间,所以我们开始了第一次的动态表单的实践。

此次动态表单实践由DevOps的CICD部分中的任务配置表单驱动,因此主要考虑的控件类型为输入框、下拉框、和代码编辑器。在实践中几个较为关键的地方分别为表单配置模型、表单联动、表单校验。


以上是较为基础的表单项的配置,我会选其中较为重要为大家说明:
attrDefId这是每一个表单项的唯一标识,前端主要用来为表单项设置ID便于获取对应元素进行其他操作;
attrId对应的是表单项对应值的字段名,即该向后端传递数据时所用的字段名,在一个完整的表单中,也是唯一的;
controlType写明了表单项类型,前端按照这项配置来决定展示的表单项是输入框、下拉框或其它指定的表单项类型;
isRequired用于配制表单校验,标识该项是否为必填项;
valueProvider是一个非常重要的配置,也相对复杂,他是一个JSON串,对于下拉框这种需要发送请求向服务端获取下拉框所需要的选项的表单项至关重要,同时也关系到表单联动的实现,其中的url代表向服务端发送请求所所使用的url是什么;
valueField表示获取到的展示数据用哪一项来作为id;
labelField表示哪一项来作为label展示给用户,multiSelect代表下拉框是否可以多选;
eventName表示当这一项的值发生改变后,会触发前端某个写好的事件做相应的处理,eventName的值就是事件名,而事件的定义由前端来实现。

表单联动主要有两种方式:
第一种是当用户修改表单中某一选项时,表单显示的内容有所变化,如图显示,当用户选择不同的介质策略时,显示的表单项也是不同的。
针对这一功能,我们目前采用的解决方案是,当表单项改变时,触发通过eventName设置的处理事件,当数据项发生改变时,针对不同的数据情况显示或隐藏表单项,这一功能需要前端事先写好处理事件然后将事件名告知后端,后端将事件名设置到需要的表单项上去。


第二种是数据联动,表单中包含代码库和branch/tag/commitId两个输入项,显然后者的显示内容取决于用户选择了哪个代码库,此处就需要前端检测用户对代码库的选择,然后将选定后的数据作为参数向后端发送请求查询branch/tag/commitId项的列表,为了解决这一问题,要求在配置动态表单的数据获取url时将需要的参数以冒号加对应表单项的字段名形式配置,示例:/repo/commit?repoId=:repoId。前端会将表单解析为一个完整的数据对象,其中每一个属性代表一个表单项,属性名采用attrId,解析后的数据对象如图所示,动态表单会将数据对象完整的传递给每一个表单项,当repoId发生改变时,branchId的对应的表单项会监听到数据对象的变化,并对其属性进行遍历,如果有其url属性所需的属性时会重写branchId的url属性并且向服务端发送新的请求获取数据源。


前面说过isRequired属性用于设置是否为必填,前端也是仅在表单项上加上了required(VUE框架下)的配置而已,并没有做更多的复杂校验。

二、问题和新需求

随着DevOps市场需求升级,我们收到了一个足以引起DevOps动态表单彻头彻尾改变的需求——工作项动态表单化配置,项目管理是DevOps的重要功能之一,6.1GA版本前的任务项管理所有的属性表单都是固定的,不支持用户做任何自定义修改,但是,这无法满足市场的需求,不同的应用场景对任务管理的要求是不一样的,比如原有的工作项仅支持故事、任务、Bug三种类型的工作项管理,每种类型的属性也是固定的,这样的用户体验较差,某些场景下用户可能需要更多类型的工作项,用户更喜欢将“故事”叫做“需求”,等等这一系列的需求,经过讨论分析,我们决定使用动态表单来实现这一功能。而原有的动态表单设置,虽然能满足CICD的任务配置,但它如果用于工作项管理配置,其缺点也是不可忽视的。因此我们决定重新制作一款更强大更灵活的动态表单。

新的动态表单需要具备如下几个主要基本功能:
  • 支持可视化页面配置表单

  • 布局自定义

  • 表单项类型自定义

  • 表单校验自定义

  • 表单联动自定义

三、动态表单进阶

为了简化用户操作,我们使用了可拖拽的页面配置形式,用户可以拖拽需要的控件或布局器到区域进行表单布局设计,还提供了可以手动配置每一个控件或布局器的属性、数据源、样式、事件(支持简单代码输入)功能。


布局方面我们支持用户以布局器(网格式)布局、标签页、折叠快、分割线四种形式,利用它们基本可以实现所有的表单布局。布局器是最基础的布局组件,支持按照纵向列的形式来配置表单布局,配置好每列数并将所需的表单项拖进对应列即可。布局器是可以嵌套的,这样一来,用户可以自行配置各种形式的页面布局。此外的标签页、折叠块、分割线都是一些辅助的展示手段,这里不在多加说明。


关于表单项类型,新的动态表单除支持全部的基础控件类型外,还支持将配置好的表单项导出为自定义控件以便复用。


剩下的问题就是表单校验自定义和表单联动自定义了,新的动态表单不再仅仅支持必填校验,还支持用户手动输入正则表达式校验,同时我们抽象了一些常用的正则表达式为默认选项供用户选择。自定义表单联动上我们沿用了初版动态表单的思路,通过事件和数据模型监听实现,在此基础上做了更加规范的处理,使用户可手动修改配置。


完成配置后,就是对动态表单配置的解析,面对如此多的表单项类型,大量的if else代码显然是不合理的,我们改用配置文件的形式,将表单类型和对应控件一个个登记在表单项字典里,然后在渲染时通过component(VUE框架下)直接渲染。对于校验规则,我们选择在渲染表单前对动态表单配置进行遍历,提取所有的校验规则,在最层统一添加校验,不再单独的表单项上做校验处理。此外还有下拉框等数据源需要向服务端发送请求的特殊控件,我们也封装了基类去对用户配置的url、参数等作统一规范化的处理,受篇幅限制这里不做详细描述。
以上是普元DevOps6.1GA版本在动态表单方面做的完善,除动态表单,我们还增加了工作项状态流转自定义配置、工作项类型自定义、工作项增删改表单自定义等一些列功能,保证用户在工作项管理上实现完完全全的自定义,让用户真正的可以按照实际应用场景自定义工作项的管理方案。

关于作者夏夏,前端工程师,参与普元DevOps产品开发,以及微服务、容器云等产品开发,负责前端页面设计、架构搭建等工作。善于架构搭建、组件封装及相关算法设计。

本文来自网络或网友投稿,如有侵犯您的权益,请发邮件至:aisoutu@outlook.com 我们将第一时间删除。

相关素材