Kendo Grid刷新后shift追加选行误选全部前置行如何解决?
问题原因分析
Kendo UI Grid的shift批量选择功能依赖内部存储的_shiftAnchor属性记录上一次选中的基准行DOM元素。刷新Grid后原有DOM被销毁重建,Grid内部存储的_shiftAnchor会被重置为空,此时按住shift点击新行时,Grid会默认从第一行作为选择起始点,就会出现全选异常。你当前只在dataBound阶段恢复了行选中状态,没有同步恢复Grid内部的多选锚点,是问题的核心原因。
解决方案
你需要额外存储最后一次选中的锚点行ID,在Grid刷新后恢复选中状态的同时,同步给Grid的内部_shiftAnchor赋值对应的行元素即可,修改点如下:
- 新增变量存储最后一次选中的锚点行ID
- 在change事件中更新锚点ID存储
- 在dataBound恢复选中后,同步恢复Grid的内部多选锚点
修改后的完整代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Kendo UI Snippet</title> <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.common.min.css"/> <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.rtl.min.css"/> <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.silver.min.css"/> <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.mobile.all.min.css"/> <script src="http://code.jquery.com/jquery-1.12.4.min.js"></script> <script src="http://kendo.cdn.telerik.com/2016.3.1028/js/kendo.all.min.js"></script> </head> <body> <button id="refresh">Refresh</button> <div id="grid"></div> <script> $(function () { var selectedOrders = []; var idField = "OrderID"; // 存储最后一次选中的锚点行ID var lastSelectedAnchorId = null; $('#refresh').click(() => { $("#grid").getKendoGrid().dataSource.read(); }) $("#grid").kendoGrid({ dataSource: { type: "odata", transport: { read: "http://demos.kendoui.com/service/Northwind.svc/Orders" }, schema: { model: { id: "OrderID", fields: { OrderID: { type: "number" }, Freight: { type: "number" }, ShipName: { type: "string" }, OrderDate: { type: "date" }, ShipCity: { type: "string" } } } }, pageSize: 10, serverPaging: true, serverFiltering: true, serverSorting: true }, height: 400, selectable: "multiple", pageable: { buttonCount: 5 }, sortable: true, filterable: true, navigatable: true, columns: [ { field: "ShipCountry", title: "Ship Country", width: 300 }, { field: "Freight", width: 300 }, { field: "OrderDate", title: "Order Date", format: "{0:dd/MM/yyyy}" } ], change: function (e, args) { var grid = e.sender; var items = grid.items(); // 更新最后选中的锚点ID var selected = grid.select(); if(selected.length > 0) { var lastSelectedItem = grid.dataItem(selected.last()); lastSelectedAnchorId = lastSelectedItem[idField]; } items.each(function (idx, row) { var idValue = grid.dataItem(row).get(idField); if (row.className.indexOf("k-state-selected") >= 0) { selectedOrders[idValue] = true; } else if (selectedOrders[idValue]) { delete selectedOrders[idValue]; } }); }, dataBound: function (e) { var grid = e.sender; var items = grid.items(); var itemsToSelect = []; // 记录锚点行元素 var anchorRow = null; items.each(function (idx, row) { var dataItem = grid.dataItem(row); if (selectedOrders[dataItem[idField]]) { itemsToSelect.push(row); // 匹配到锚点ID则记录行元素 if(dataItem[idField] === lastSelectedAnchorId) { anchorRow = row; } } }); e.sender.select(itemsToSelect); // 恢复Grid内部的多选锚点 if(anchorRow) { grid._shiftAnchor = anchorRow; } } }); }); </script> </body> </html>
注意事项
如果后续升级Kendo UI版本,若出现功能失效可以查看Grid内部存储shift锚点的属性名是否有变更,核心逻辑就是刷新后同步恢复内部锚点即可解决问题。
内容的提问来源于stack exchange,提问作者User1899289003
相关产品推荐
相关产品推荐

