小程序表单动态配置与表单联动 - 实现篇

2021-02-20  本文已影响0人  前端C罗

表单(form)是用户填写(输入)信息的重要交互UI元素,所有需要收集信息的页面均会使用到表单。

表单在桌面应用、app、web应用、小程序等均被广泛应用,各个平台上开发表单相关的功能在实现上也会有些不同,而对于表单的配置、联动也是很多开发者需要面临并尝试解决的难题。

在微保小程序的年金产品投保模块,也涉及到表单的相关处理,有些自己理解,抛出来大家一起讨论。
先看一张报价区域表单信息的截图,这是一个比较常见的投保报价表单模块。


报价模块表单截图

从图中可以直观看出,表单模块的一些特点:

语义鲜明是报价表单模块较为突出的特性,用户的报价是要基于这些语义项的值,意味着表单组件要能够承担起内部控件数据向语义准确的请求数据转换的职责。页面初始化及用户通过操作控件带来的数据变化要能够被包装成固定格式的request data
就像是一个完整的采购-加工-输出的流程

流程类比图

笔者认为要解决表单模块的配置化、表单联动需要解决下列问题

围绕上述4个问题,笔者将会介绍在小程序环境下如何实现投保模块表单的配置、更新、数据维护、联动。

表单数据与视图

整个表单的配置化与显示是数据到视图的映射,因此数据、模板是表单的重要组成部分

表单组成
表单对应的配置数据笔者使用json格式,在对表单进行配置之前,将表单模块进行分层。表单可以拆解到表单项,进而再进一步拆解到控件,先一起看看下图的拆解。 表单项

从图中可以看出,一个完整的表单模块可能是有N(N >= 1)个表单项,很多复杂的表单模块甚至有多层嵌套;同时,每个表单项有自己清晰的标题用以说明此项的业务含义、有明确的表单项状态(编辑态、预览态、隐藏或显示)、有自封闭的控件完成用户相关的信息输入。

进一步抽象出相应的配置如下


表单数据抽象结构

对上述的脑图进行一些说明

整个流程涉及到配置服务、控件开发、表单组件封装、表单模块数据维护等。视图的呈现使用数据驱动,而表单内部的变动会以自定义事件的形式抛出,表单内部的联动使用发布-订阅的方案。
为了适配业务的诉求、控件复用,对整个表单组件进行分层,如下图所示

Form组件分层
上层Form组件以事件冒泡的形式,抛出update的事件,供业务方监听处理,同时对外提供初始化,状态获取,更新视图等接口。相应的类图如下:
分层类图

控件均从抽象基类派生,需要实现相应的抽象方法,控件作为用户实际操作的交互单元,整个表单模块对其的状态变更和数据获取需要能非常便捷触达。同时,受益于整个架构的分层,控件的引入可以自己开发、也可以引入第三方的控件库,只需要做少量的适配工作即可。

表单联动

简单理解就是不同的表单行(联动的粒度是表单行)之间存在制约关系,一个表单行的值会影响其他若干表单行的值域、状态、显示与隐藏。
配置数据通过初始化驱动表单视图显示,用户打开此视图后,会根据实际情况、个人喜好操作表单,由此导致相应的数据值发生变化。即使是同类型但不同的保险公司推出的保险产品,其受限规则可能都是不同的。
但不管是哪种情况,表单联动要解决的核心问题有2个

为解决这2个问题,配置中引入triggersaction的概念。整个模型基于事件总线和event loop机制,用户操作会触发控件的change事件,表单行捕获change事件,通过数据包装,在总线上广播自身变动的事件,监听相关事件的表单行,执行action中下发的js脚本

联动机制
整个机制完全的配置化有一个绕不过的问题,那就是如何执行下发的js脚本
众所周知,小程序不支持eval执行脚本代码字符串,但可以通过引入或实现js解析与执行的引擎来解决此问题。
整个流程如下图: 实现js简易引擎的流程

社区中有比较成熟稳定的AST生成库,比如acornbabylon等,开发者可以在此基础上实现解释器即可完成目标。感兴趣的读者可以参考前端编译原理 这篇文章,本文不赘述。
引入动态脚本的执行能力就像是一把双刃剑,它给配置策略的实现带来极大的灵活性,但同时,它的安全性、调试的便捷性也是面临的问题。基于这些考量,对下发的脚本做如下约束:

表单更新&数据维护

表单模块与业务页面或其他组件交互的实质是表单模块在特定时间点的结构化数据的共享。表单模块内部通过属性设置、事件冒泡完成数据在内部的循环。


数据通信模型

上图中,可以比较形象地看出表单的更新及数据的获取方案

回顾整个方案的设计和实现,成功解决了本文开始提到的4个问题,并且具备以下优势

欢迎各位读者拍砖。

上一篇 下一篇

猜你喜欢

热点阅读