记住在 Kendo-UI 中刷新时扩展的细节网格
Posted
技术标签:
【中文标题】记住在 Kendo-UI 中刷新时扩展的细节网格【英文标题】:Remember expanded detail grids on refresh in Kendo-UI 【发布时间】:2012-08-19 04:35:07 【问题描述】:我有一个使用 detailInit 方法实现的网格内网格场景。在这里,当用户进行编辑时,我会进行一些计算,这些计算会更改父子节点中的数据。然后刷新数据,我将调用 datasource.read 来呈现数据。这有效并且显示了数据,但是任何展开的细节网格都会被折叠,有什么办法可以防止这种情况发生。
【问题讨论】:
【参考方案1】:回答这个问题和另一个问题:
“我想出了如何从孩子那里设置主数据,但是, 更新任何内容时,整个表格都会折叠子网格,这是 非常烦人的行为,无论如何我可以更新一个字段 没有它折叠所有子元素的主表? (基本上,更新列,不更新海量表)"
在另一个线程中:telerik
这是 Kendo Grid 极其烦人的行为,也是一个重大错误。从什么时候开始有人希望子网格消失并隐藏刚刚进行的更改!但这不是唯一的问题。更改函数被调用斐波那契数次,这将在大量点击后冻结浏览器。话虽如此,这是我想出的解决方案:
在主网格中
$('#' + 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()' 函数放在 subgrid 'datasource' 中,如下所示:
dataSource: function (e)
var ds = new kendo.data.DataSource(
...
create: false,
schema:
model:
...
,
change: function (e)
subgridChange();
);
return ds;
我还必须使用类似这样的方法将“subgridChange()”函数放在“添加”按钮函数中
$('<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();
);
【讨论】:
【参考方案2】:当用户选择一行时,记录所选行的索引。然后在你的数据刷新之后,使用下面的代码展开一行
// 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()
选择器中的数字更改为您要展开的行的索引。
【讨论】:
您建议如何记录展开的行并在刷新时将其传递给网格? 我没有这个来源。当您右键单击 > 检查数据行时。是否有任何表示扩展行的数据属性?如果是,请使用 jquery 选择器选择具有所需属性的元素。【参考方案3】:其实只需要主网格“dataBound”函数中的“subgridChange()”函数即可:
$('#' + grid_id).kendoGrid(
...
dataBound: function (e)
gridDataMap.subgridChange();
);
【讨论】:
【参考方案4】:我用于相同问题的不同但相似的解决方案:
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;
【讨论】:
以上是关于记住在 Kendo-UI 中刷新时扩展的细节网格的主要内容,如果未能解决你的问题,请参考以下文章
使用keepAlive对上下拉刷新列表数据 和 滚动位置细节处理 - vue