Jsonz bug-log

后续更新会放在 github.com/jsonz1993/blog

0%

业务表单自动保存引发的小思考

最近接到一个表单自动保存的需求,一开始以为只是简单的数据保存,抄起键盘就干,十行代码不到实现个大概的:

1
2
3
4
5
6
7
setInterval(() => {
localStorage.setItem('paymentData', JSON.stringify(paymentData))
}, 1000 * 10)

init() {
paymentData = JSON.parse(localStorage.getItem('paymentData'))
}

看需求是要pc端和app端同步,好像也不难,只是把保存到localStorage的过程改成保存到服务端,但是实际做起来问题倒是挺多的。

Q: 实现的基本思路

A: 项目一直尝试MVC模式,也有一点DDD的味道。所以虽然pc端和app端有很大的差异,但是模式差不多,表单一般都由一个具体的表单模型去驱动。所以基本的思路是,pc端和app端分别是两个不同的model,那就基于这两个model去抽离出一套通用的数据格式。
然后基于这份数据格式,存的时候pc和app转换成该数据格式,拉取的时候又分别根据这份数据转换为自己需要的格式存到model里。
除了存的这些格式外,还需要做一套接口,比如某个字段变动之后,会调用接口去异步查询,或者某几个字段有联动。比如支付金额超过4000万,且支付币种为美金时需要调接口去查询是否需要拆单。
有了基本的思路就开始实现了…

Q: 一些组件不是瓦全由数据驱动的,有一些是行为触发,所以你数据一致并不能百分百的还原当时的组件状态。

A: 对这个问题,没有特别好的办法,属于历史留下的包袱,解决的方法就是直接去改造这个组件。因为这些其实属于一个bug,只是以前一直没有这种 time travel 的场景,所以没有被发现。

Q: 一些数据属于临时状态,业务表单的时候不需要提交到服务端,但是他又会影响到一些业务判断。

A: 把这些数据也存起来,可以在 getSaveData() 的时候手动给他拼接进去。

Q: 一些字段有联动,比如字段改动后回触发异步请求去校验,或者拉取其他的新数据。

A: 封装一套工具,做一些通用的hook,比如每个字段填充之前调用接口,自定义填充方式,全部填充后调用一些初始化的接口等等。配置大致可以如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
delay?: number,
namespace: string,
interval?: number,

fillBackItem?: ({ key, value, data }) => void,
preFillBackItem?: ({ key, value, data }) => void,
postFillBackItem?: ({ key, value, data }) => void,
preFillBackItem?: data => void,
postFillBackItem?: data => void,

getSaveData: () => Data, // 需要保存的数据
preSaveData?: Data => Data,
postSaveData?: Data => void,

keysConfig?: (string | {
key: string,
getValue4Save?: (value, data) => value,
fillBack: ({ key, value, data }) => void,
preFillBack: ({ key, value, data }) => void,
postFillBack: ({ key, value, data }) => void,
})[]
}

但是最好的做法还是在 pc和 app统一一套支付的model,然后在model层做,这才是我认为的最优解。把业务无关的抽离成模型去框架化,这样不管你用的是angular,react还是vue都可以公用一套,这对于我们项目来说是非常实用的。不过由于诸多历史包袱,现在还没有实现,但是已经在路上了。