Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

业务表单自动保存引发的小思考:2021-7-16 #28

Open
jsonz1993 opened this issue Jul 27, 2021 · 0 comments
Open

业务表单自动保存引发的小思考:2021-7-16 #28

jsonz1993 opened this issue Jul 27, 2021 · 0 comments

Comments

@jsonz1993
Copy link
Owner

本文为博客迁移过来,原文链接: 业务表单自动保存引发的小思考:2021-7-16

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

  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,比如每个字段填充之前调用接口,自定义填充方式,全部填充后调用一些初始化的接口等等。配置大致可以如下:

{
	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都可以公用一套,这对于我们项目来说是非常实用的。不过由于诸多历史包袱,现在还没有实现,但是已经在路上了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant