如何在 dgrid 中使用 dnd 实现行重新排序
Posted
技术标签:
【中文标题】如何在 dgrid 中使用 dnd 实现行重新排序【英文标题】:How to implement row reordering with dnd in dgrid 【发布时间】:2013-01-25 15:49:05 【问题描述】:我在 dgrid 中创建了一个连接到 JsonRest 存储的网格。这会从金字塔后端加载数据。我还在商店中添加了 DnD 扩展。 DnD 有效,但是当我拖动行时,我不知道如何让它发送任何有意义的数据。目前它发送两个请求,一个 GET 和一个 PUT,但 PUT 只包含行中的数据,但没有任何东西可以用来更新数据库中的顺序。
那么在我的网格中需要什么配置,才能获得新的订购信息?
【问题讨论】:
嗨,你想好这个了吗?我今天遇到了同样的问题。 我担心这需要对商店进行子类化,但是让我们尝试一下。 你能提供一个jsfiddle吗? 拖动行时的意图是什么?大概 Db 中的数据是按某个字段排序的。如果您拖动行,那么您需要更新该字段以给出新的顺序,这意味着如果说您将“7”拖到“5”之前,那么 7 变为 5,5 变为 6,6 变为 7。这是你的意图吗?我的直觉是,您需要更新商店中的数据以反映此更改,然后触发更新。 我采用的方法与@djna 描述的完全一样。有关详细信息,请参阅下面的答案。 【参考方案1】:这就是我的工作:
-
在数据库中维护一个
position
列
当一行被删除时调用 store.put,传递被删除项的 id 和它被删除的位置。
更新位置时,相应地移动其他项目
这是我的onDropInternal
函数。它也处理删除多行:
onDropInternal: function(nodes, copy, targetItem)
var store = this.grid.store, grid = this.grid, targetRow, targetPosition;
if (!this._targetAnchor) return
targetRow = grid.row(this._targetAnchor);
targetPosition = parseInt(targetRow.data[grid.orderColumn]);
responses = 1;
nodes.forEach(function(node, idx)
targetPosition += idx;
var object = id:grid.row(node).id;
object[grid.orderColumn] = targetPosition;
store.put(object).then(function()
if (responses == nodes.length) grid.refresh();
else responses++;
);
);
这是我用来更新位置的 php 代码。 $fields
是一个关联数组,表示要存储的记录。它还假设存在两个函数:query
和 query_row
,如果您选择使用此技术,我相信您可以处理替换。
$table = "my_table";
$field = "position_field";
if (empty($fields['id']))
//for new records, set the position field to the max position + 1
$h = query_row("SELECT MAX(`$field`) as highest FROM $table LIMIT 1");
$fields[$field] = $h['highest']+1;
else if (is_numeric($fields[$field]))
//we want to move the row to $target_position
$target_position = $fields[$field];
//first get the original position
$row = query_row("SELECT id,$field FROM $table WHERE id='$fields[id]' LIMIT 1");
//start a list of ids
$ids = $row['id'];
//if the original position is lower than the target postion, set the incrementor to -1, otherwise 1
$increment = ($row[$field] < $target_position) ? -1 : 1;
//start a while loop that goes as we long as we have a row trying to take a filled position
while (!empty($row))
//set the position
query("UPDATE $table SET $field='$target_position' where id='$row[id]'");
//get the other row with this position (if it exists)
$row = query_row("SELECT id,$field FROM $table WHERE id NOT IN ($ids) && `$field`='$target_position' LIMIT 1");
//add it's id to the list of ids to exclude on the next iteration
$ids .= ", ".$row['id'];
//increment/decrement the target position
$target_position += $increment;
您可以通过使用一次更新多条记录的查询来提高效率,但这样做的好处是它可以很好地处理位置编号中的意外间隙。
【讨论】:
以上是关于如何在 dgrid 中使用 dnd 实现行重新排序的主要内容,如果未能解决你的问题,请参考以下文章
如何在 swift 中使用 fetchedresultscontroller 重新排序 tableview 行?
当用户完成列重新排序时如何防止 renderHeaderCell() 调用