markdown 拖放排序:设计与实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown 拖放排序:设计与实现相关的知识,希望对你有一定的参考价值。
Drag-drop sort: Design & Implementation
=======================================
[TOC]
## References
- https://www.v2ex.com/t/400011
- https://www.zhihu.com/question/55789722
## Data Models
Take `Project` and `Task` for example:
```python
class Project(Model):
pass
class Task(Model):
POSITION_STEP = 2**16
project = ForeignKey(Project)
position = Number(default=POSITION_STEP, allow_none=False) # position in project it belonged to
```
## Front-end/Server Interaction
The server send tasks by position in ascending order.
The front-end don't need to care `Task.position`. Front-end stores tasks in an ordered list.
While user move a task up/down, just change the ordered list, at the same time send a request telling server the task's new place, like below:
```
## Add a new task with postion-spec
POST /tasks/
{
"project": "project-001",
// If you are adding the first task, just ignore the "position" key
"position": {
"before": "task-A", // set null if put at end
"after": "task-B" // set null if put at top
}
// ...
}
## Update a task with postion-spec
PATCH /tasks/task-C
{
"project": "project-001",
"position": {
"before": "task-A", // set null if move to the end
"after": "task-B" // set null if move to the top
}
// ...
}
```
Note the front-end doesn't calculate the position(it's server's responsibility),
also doesn't care the new postision responded by server(because front-end maintains the same order via its ordered list).
## Server Implementation
- When creating the first task, no postion-spec is required from client.
saving the task with position `65536`(the default value).
- When put a task between two tasks: `position = (before.position + after.position) / 2`
- When put a task at end: `position = after.position + Task.POSITION_STEP`
- When put a task at top: `position = before.position - Task.POSITION_STEP`
If the calculated position is not an integer or `abs(position - after.position) < 2`,
Then all tasks' position values **requires reassignment with the same order**:
Fake code for reassignment:
```python
def rearange_tasks_position(project):
def make_pos_generator(cursor=1):
while True:
yield Task.POSITION_STEP * cursor
cursor += 1
pos_generator = make_pos_generator()
for task in db.query(Task).filter_by(project=project).sort('position', 'ASC').all():
task.position = next(pos_generator)
task.save()
```
## Terms
### position-spec
A structure like below:
```json
{
"before": "some-task-id",
"after": "some-task-id"
}
```
`before` and `after` mustn't be all missing.
以上是关于markdown 拖放排序:设计与实现的主要内容,如果未能解决你的问题,请参考以下文章