我有一个使用detailInit方法实现网格中网格的场景。在这里,当用户进行编辑时,我会进行一些计算,以更改父级和子级中的数据。然后为了刷新数据,我将调用datasource.read来呈现数据。这是有效的,数据是显示的,但是任何扩展的细节网格都会被折叠,我有什么办法可以防止这种情况发生吗。
回答这个和另一个问题:
"我从孩子那里学会了如何在master中设置数据,但是当任何内容更新时,整张表都会折叠子网格,这是非常烦人的行为,有没有我可以更新中的字段不折叠所有子元素的主表?(基本上,更新列,不更新质量表)"
在另一个线程中:telerik
这是剑道网格极其令人讨厌的行为,也是一个主要的错误。从什么时候开始,一个人希望子网格消失并隐藏刚刚做出的更改!但这并不是唯一的问题;change函数被调用了多次Fibonacci,这将在大量点击后冻结浏览器。话虽如此,以下是我提出的解决方案:
在主电网中
$('#' + grid_id).kendoGrid({
width: 800,
...
detailExpand: function (e) {
var grid = $('#' + grid_id).data("kendoGrid");
var selItem = grid.select();
var eid = $(selItem).closest("tr.k-master-row").attr('data-uid')
if (contains(expandedItemIDs, eid) == false)
expandedItemIDs.push(eid);
},
detailCollapse: function (e) {
var grid = $('#' + grid_id).data("kendoGrid");
var selItem = grid.select();
var eid = $(selItem).closest("tr.k-master-row").attr('data-uid')
for (var i = 0; i < expandedItemIDs.length; i++)
if (expandedItemIDs[i] == eid)
gridDataMap.expandedItemIDs.splice(i, 1);
},
不幸的是,在全球范围内,我们有:
function subgridChange() {
var grid = $('#' + grid_id).data("kendoGrid");
for (var i = 0; i < expandedItemIDs.length; i++)
grid.expandRow("tr[data-uid='" + expandedItemIDs[i] + "']");
}
function contains(a, obj) {
for (var i = 0; i < a.length; i++)
if (a[i] === obj) return true;
return false;
}
expandedItemIDs = [];
现在,每次对子网格进行更改时都需要调用"subgridChange()"函数。
问题是,子网格中的更改函数在每次更改调用时被调用的次数呈指数级增加。Kendo网格应该能够调用停止传播函数来防止这种情况,或者至少允许程序员访问事件对象,这样程序员就可以防止传播。在完全恼火之后,我们所要做的就是将"subgridChange()"函数放在子网格的"datasource"中,如下所示:
dataSource: function (e) {
var ds = new kendo.data.DataSource({
...
create: false,
schema: {
model: {
...
}
},
change: function (e) {
subgridChange();
}
});
return ds;
}
我还必须使用类似的东西将"subgridChange()"函数放在Add按钮函数中
$('<div id="' + gridID + '" data-bind="source: prodRegs" />').appendTo(e.detailCell).kendoGrid({
selectable: true,
...
toolbar: [{ template: "<a class='k-button addBtn' href='javascript://'><span class='k-icon k-add' ></span> Add Product and Region</a>" }]
});
$('.addBtn').click(function (event) {
...
subgridChange();
});
当用户选择一行时,记录所选行的索引。然后在数据刷新后,使用以下代码展开一行
// get a reference to the grid widget
var grid = $("#grid").data("kendoGrid");
// expands first master row
grid.expandRow(grid.tbody.find(">tr.k-master-row:nth-child(1)"));
要展开不同的行,只需将nth-child()
选择器中的数字更改为要展开的行的索引即可。
实际上所需要的只是主网格"dataBound"函数中的"subgidChange()"函数:
$('#' + grid_id).kendoGrid({
...
dataBound: function (e) {
gridDataMap.subgridChange();
}
});
我对同一问题使用的不同但相似的解决方案:
expandedItemIDs = [];
function onDataBound() {
//expand rows
for (var i = 0; i < expandedItemIDs.length; i++) {
var row = $(this.tbody).find("tr.k-master-row:eq(" + expandedItemIDs[i] + ")");
this.expandRow(row);
}
}
function onDetailExpand(e) {
//refresh the child grid when click expand
var grid = e.detailRow.find("[data-role=grid]").data("kendoGrid");
grid.dataSource.read();
//get index of expanded row
$(e.detailCell).text("inner content");
var row = $(e.masterRow).index(".k-master-row");
if (contains(expandedItemIDs, row) == false)
expandedItemIDs.push(row);
}
function onDetailCollapse(e) {
//on collapse minus this row from array
$(e.detailCell).text("inner content");
var row = $(e.masterRow).index(".k-master-row");
for (var i = 0; i < expandedItemIDs.length; i++)
if (expandedItemIDs[i] == row)
expandedItemIDs.splice(i, 1);
}
function contains(a, obj) {
for (var i = 0; i < a.length; i++)
if (a[i] === obj) return true;
return false;
}