产品的PRD画的原型图有这么一种操作,网上搜了半天不知道叫什么名字,后来在AngularJS Material的DEMO上找到了这种交互方式,分类在Chips下,中文的意思大概是木屑,纸片之类的,就姑且叫做Chips交互
Chips交互的主要操作方式通过肉眼就可以识别:
- 增加一个项目
- 删除一个项目
这两个操作由前端实现,只是在页面上展示,实际上并没有在数据的持久层保存下来
真正与数据库打交道的隐藏逻辑有:
- 隐藏操作: 列出所有项目(list),比如Apple、Banana、Orange
- 隐藏操作: 新增若干项目(insert),比如增加一个Cherry
- 隐藏操作: 删除若干项目(delete), 比如删除一个Banana
- 隐藏操作: 修改项目组(update), 提交or保存的时候,更新整个group,比如Apple、Orange、Cherry
页面的交互逻辑,看起来很简单,但是服务端实现起来,就一不小心衍生出了很多小九九的想法
这些和数据库打交道的隐藏操作,甚至在数据库的字段设计上都可以有所讲究
我们举个例子,假设我要完成如下操作——称之为操作X:
1. 打开页面,载入已有的fruit: Apple、Banana、Orange
2. 删除✗掉一个fruit: Banana
3. 新增一个fruit: Cherry
4. 提交保存,更新fruit数据
全部删除后重写
数据库中的初始值如下,其中每种水果是一个记录
auto_id | fruit |
---|---|
1 | Apple |
2 | Banana |
3 | Orange |
执行完操作X之后,数据库中的值变成:
auto_id | fruit |
---|---|
4 | Apple |
5 | Orange |
6 | Cherry |
对应的SQL是:
DELETE * FROM T_Fruit;
INSERT INTO T_Fruit VALUES("Apple"), ("Orange"), ("Cherry");
高大上的集合论
数学才是王道,所以工程实现上能沾上数学的边,用集合来搞,自然高大上
所以我们的操作X可以归结为集合Old_Set
和集合New_Set
的集合操作
在服务端,我们需要保留Old_Set
和New_Set
共有的(交集),删掉Old_Set
单有的,添加New_Set
单有的
不过这里采用了集合的差来构造更新集合Updae_Set
和删除集合Delete_Set
:
deteteSet = Sets.difference(olderSet, newerSet);
insertSet = Sets.difference(newerSet, olderSet);
之后改删除的删除该更新的更新,结果数据库为:
auto_id | fruit |
---|---|
1 | Apple |
3 | Orange |
4 | Cherry |
讨巧的字符串
后来和别人交流,发现还有这种取巧的方式
数据库的初始值这么存储:
auto_id | fruit |
---|---|
1 | Apple,Banana,Orange |
执行操作X,就直接替换fruit的值,这种做法只需要一个记录即可:
auto_id | fruit |
---|---|
2 | Apple,Orange,Cherry |
至于页面上的分割效果,就留给前端发挥好了