teambition的任务卡排序,数据是怎么存储的?
teambition的任务卡支持拖拽排序,如果从最底下拖到最顶部,数量很多时,是怎么去存这个新的顺序的?应该不会选择最暴力的方式,把每个任务卡的排序值…
关注者
121被浏览
30,5124 个回答
刚好这个功能是我和
@isayme做的, 可以来答一下。
初始的时候每个任务在数据库中都有一个 order 值
{
"_id": "xxxxx",
"order": 100
}
然后相邻的任务间的 order 值有一个很大的差值,比如:
{
"_id": "xxxxx",
"name": "task 1",
"order": 100
}
{
"_id": "xxxxx",
"name": "task 2",
"order": 500
}
在用户拖拽重新排序的时候,前端会发一个 `put` 请求更新任务的 order 值:
// put /api/tasks/xxxx
const newOrder = (nextOrder - lastOrder) / 2
{
_id: 'xxxx',
order: newOrder
}
这个 newOrder 是前端计算出来的 nextOrder 与 lastOrder 的中间值(不需要为整数,只需要保证比前一条任务的 order 大比后一条任务的 order 小即可)。后端接受到这个值之后会计算出它新的位置,并根据新的位置计算出新的 order 值(和前端计算出来的不一样)。
然后判断这个新的 order 值是否在安全范围内:即它与上一个/下一个 任务的 order 差是否过小,如果比安全值大则将新的 order 插入数据库然后返回新的 order,前端以新的 order 为真正的任务 order。
如果比安全值小则对整个任务分组的任务 order 重计算。然后通过 socket 发送一条 stage/refresh 消息通知前端重新拉取整个任务阶段的任务(概率极小)。
谢 @太狼 邀.
问题"最底下拖到最顶部"的答案: 通常都是仅更新被移动任务的位置信息.
两个前提:
- 位置的信息记录在任务的模型上(pos字段);
- 一般两个任务的pos值相差很大(默认是65536);
现在假设有任务 A, B, C. 列举几个常见的场景:
- 如果C要移到A的前面, 那么后端会把 C.pos 改为 A.pos/2;
- 若果C要移到A和B之间, 那么后端会把 C.pos 改为 (A.pos + B.pos)/2;
- 如果B要移到C的后面, 那么后端会把 B.pos 改为 C.pos + 65536;
当然这里会有个极端情况需要处理(假设pos是整数):
如果 A.pos 是 1, B.pos 是 2, C想移到A和B之间, 其实是没有一个整数可以用的, 针对这种情况, 后端会重新给整个列表的任务重新刷一遍pos值.
更改任务位置时, 后端之所以不直接使用前端传的pos值是为了避免人为的创造极端场景...