Kendo UI 添加新记录后网格拖放停止工作
Kendo UI grid drag&drop stops working after adding new record
我有 Kendo UI 具有拖放功能的网格:
var data = [
{ id: 1, text: "text 1", position: 0 },
{ id: 2, text: "text 2", position: 1 },
{ id: 3, text: "text 3", position: 2 },
{ id: 4, text: "text 4", position: 40 },
{ id: 5, text: "text 5", position: 100 },
{ id: 6, text: "text 6", position: 600 },
{ id: 7, text: "text 7", position: 47000 },
{ id: 8, text: "text 8", position: 99999 },
{ id: 9, text: "text 9", position: 1000000 }];
var dataSource = new kendo.data.DataSource({
data: data,
schema: {
model: {
id: "id",
fields: {
id: { type: "number" },
text: { type: "string" },
position: { type: "number" }
}
}
}
});
var grid = $("#grid").kendoGrid({
dataSource: dataSource,
scrollable: false,
editable : "popup",
columns: ["id", "text", "position"],
toolbar: ["create"]
}).data("kendoGrid");
var createDraggable = function() {
grid.table.find("tbody tr").kendoDraggable({
cursorOffset: {
top: 10,
left: 10
},
group: "gridGroup",
hint: function(e) {
return $('<div class="k-grid k-widget" style="color:red"><table><tbody><tr>' + e.html() + '</tr></tbody></table></div>');
}
});
grid.table.find("tbody tr").kendoDropTarget({
dragenter: function (e) {
var target = grid.dataSource.getByUid($(e.draggable.currentTarget));
$(e.dropTarget[0]).addClass("highlight-droparea");
// e.dropTarget.addClass("highlight-droparea");
console.log('entering');
},
dragleave: function (e) {
$(e.dropTarget[0]).removeClass("highlight-droparea");
//e.dropTarget.removeClass("highlight-droparea");
console.log('leaving');
},
group: "gridGroup",
drop: function(e) {
var target = grid.dataSource.getByUid($(e.draggable.currentTarget).data("uid")),
dest = $(e.target);
if (dest.is("th") || dest.is("thead") || dest.is("span") || dest.parent().is("th")) {
return;
}
//in case the grid contains an image
else if (dest.is("img")) {
dest = grid.dataSource.getByUid(dest.parent().parent().data("uid"));
} else {
dest = grid.dataSource.getByUid(dest.parent().data("uid"));
}
//not on same item
if (target.id !== dest.id) {
//reorder the items
var tmp = target.get("position");
target.set("position", dest.get("position"));
dest.set("position", tmp);
//Lets mark the changes as dirty
target.dirty = true;
dest.dirty = true;
grid.dataSource.sort({ field: "position", dir: "asc" });
}
createDraggable();
}
});
};
createDraggable();
如果您创建新记录或在创建新行时点击 "Cancel",拖放操作将停止。我认为同样的问题会出现在所有网格 CRUD 操作中。
有什么解决办法吗?
这个问题的发生是因为kendo 重绘所有行(所有DOM元素)在每个动作上再次,例如save
, cancel
,所以任何附加到 DOM 的事件都将丢失。
您所要做的就是对这些事件调用 createDraggable()
以重新创建所有拖放功能。请注意,如果您的网格很大,这可能会很糟糕。
以下为网格事件:
cancel: function() {
window.setTimeout(function() {
createDraggable();
}, 1);
},
save: function() {
window.setTimeout(function() {
createDraggable();
}, 1);
}
是的,它很丑。 setTimeout
的目的是模拟 after 事件,因为这些事件的调用类似于 before。我的意思是,它们在 DOM 发生更改之前被调用,我们需要在此之后应用拖放,否则它们将再次全部丢失。所以计时器在更改完成后立即执行,我们得到一个 after 事件。您还有 remove
and edit
个活动。
我有 Kendo UI 具有拖放功能的网格:
var data = [
{ id: 1, text: "text 1", position: 0 },
{ id: 2, text: "text 2", position: 1 },
{ id: 3, text: "text 3", position: 2 },
{ id: 4, text: "text 4", position: 40 },
{ id: 5, text: "text 5", position: 100 },
{ id: 6, text: "text 6", position: 600 },
{ id: 7, text: "text 7", position: 47000 },
{ id: 8, text: "text 8", position: 99999 },
{ id: 9, text: "text 9", position: 1000000 }];
var dataSource = new kendo.data.DataSource({
data: data,
schema: {
model: {
id: "id",
fields: {
id: { type: "number" },
text: { type: "string" },
position: { type: "number" }
}
}
}
});
var grid = $("#grid").kendoGrid({
dataSource: dataSource,
scrollable: false,
editable : "popup",
columns: ["id", "text", "position"],
toolbar: ["create"]
}).data("kendoGrid");
var createDraggable = function() {
grid.table.find("tbody tr").kendoDraggable({
cursorOffset: {
top: 10,
left: 10
},
group: "gridGroup",
hint: function(e) {
return $('<div class="k-grid k-widget" style="color:red"><table><tbody><tr>' + e.html() + '</tr></tbody></table></div>');
}
});
grid.table.find("tbody tr").kendoDropTarget({
dragenter: function (e) {
var target = grid.dataSource.getByUid($(e.draggable.currentTarget));
$(e.dropTarget[0]).addClass("highlight-droparea");
// e.dropTarget.addClass("highlight-droparea");
console.log('entering');
},
dragleave: function (e) {
$(e.dropTarget[0]).removeClass("highlight-droparea");
//e.dropTarget.removeClass("highlight-droparea");
console.log('leaving');
},
group: "gridGroup",
drop: function(e) {
var target = grid.dataSource.getByUid($(e.draggable.currentTarget).data("uid")),
dest = $(e.target);
if (dest.is("th") || dest.is("thead") || dest.is("span") || dest.parent().is("th")) {
return;
}
//in case the grid contains an image
else if (dest.is("img")) {
dest = grid.dataSource.getByUid(dest.parent().parent().data("uid"));
} else {
dest = grid.dataSource.getByUid(dest.parent().data("uid"));
}
//not on same item
if (target.id !== dest.id) {
//reorder the items
var tmp = target.get("position");
target.set("position", dest.get("position"));
dest.set("position", tmp);
//Lets mark the changes as dirty
target.dirty = true;
dest.dirty = true;
grid.dataSource.sort({ field: "position", dir: "asc" });
}
createDraggable();
}
});
};
createDraggable();
如果您创建新记录或在创建新行时点击 "Cancel",拖放操作将停止。我认为同样的问题会出现在所有网格 CRUD 操作中。
有什么解决办法吗?
这个问题的发生是因为kendo 重绘所有行(所有DOM元素)在每个动作上再次,例如save
, cancel
,所以任何附加到 DOM 的事件都将丢失。
您所要做的就是对这些事件调用 createDraggable()
以重新创建所有拖放功能。请注意,如果您的网格很大,这可能会很糟糕。
以下为网格事件:
cancel: function() {
window.setTimeout(function() {
createDraggable();
}, 1);
},
save: function() {
window.setTimeout(function() {
createDraggable();
}, 1);
}
是的,它很丑。 setTimeout
的目的是模拟 after 事件,因为这些事件的调用类似于 before。我的意思是,它们在 DOM 发生更改之前被调用,我们需要在此之后应用拖放,否则它们将再次全部丢失。所以计时器在更改完成后立即执行,我们得到一个 after 事件。您还有 remove
and edit
个活动。