刷新后剑道网格单元重新聚焦
Posted
技术标签:
【中文标题】刷新后剑道网格单元重新聚焦【英文标题】:Kendo grid cell refocusing after refresh 【发布时间】:2014-05-07 17:31:08 【问题描述】:我有一个可选择、可导航和可编辑的网格。在单元格中输入值后,我必须更改更新单元格下的单元格中的值。要显示两个单元格的更新值,我必须刷新网格。当我这样做时,编辑的单元格失去焦点。我找到了一种在保存事件期间重新聚焦最后编辑的单元格的方法:
save: function (e)
var focusedCellIndex = this.current()[0].cellIndex; //gets the cell index of the currently focused cell
//...some dataItem saving (dataItem.set()) logic...
this.refresh(); //refreshing the grid instance
setTimeout(function () //refocusing the cell
return function ()
var focusedCell = $("#grid tr[data-uid='" + dataItem.uid + "'] td:nth-child(" + (focusedCellIndex + 1) + ")");
$('#grid').data('kendoGrid').editCell(focusedCell);
(), 200);
问题是这是第一次工作,但如果我再次尝试重新编辑同一个单元格,单元格就会失去焦点。当我尝试调试时,似乎this.current()[0].cellIndex
在第二次尝试中返回 0,并且由于该单元格聚焦不再起作用。
有谁知道为什么this.current()
第一次工作,而不是第二次工作?还有其他方法可以重新聚焦单元格吗?
【问题讨论】:
【参考方案1】:如果没有在演示中看到它,很难准确地说出正在发生的事情,所以如果可以的话,我建议创建一个用于说明。我猜对 refresh
的调用正在删除当前的单元格选择并关注第一个单元格,因为网格是可导航的(我不太明白这种行为背后的基本原理,但很难说这是否是一个错误,因为我们无法阅读 Telerik 的代码 cmets)。
一种可行的方法是修改current
方法以同时存储当前单元格索引:
kendo.ui.Grid.fn.refresh = (function(refresh)
return function(e)
this._refreshing = true;
refresh.call(this, e);
this._refreshing = false;
)(kendo.ui.Grid.fn.refresh);
kendo.ui.Grid.fn.current = (function(current)
return function(element)
// assuming element is td element, i.e. cell selection
if (!this._refreshing && element)
this._lastFocusedCellIndex = $(element).index(); // note this might break with grouping cells etc, see grid.cellIndex() method
this._lastFocusedUid = $(element).closest("tr").data("uid");
return current.call(this, element);
)(kendo.ui.Grid.fn.current);
kendo.ui.Grid.fn.refocusLastEditedCell = function ()
if (this._lastFocusedUid )
var row = $(this.tbody).find("tr[data-uid='" + this._lastFocusedUid + "']");
var cell = $(row).children().eq(this._lastFocusedCellIndex);
this.editCell(cell);
;
这样,您应该始终能够在需要时使用grid.refocusLastEditedCell()
。
另一个想法:
save: function (e)
var focusedCell = this.current();
var focusedCellIndex = focusedCell.index(); //gets the cell index of the currently focused cell
//...some dataItem saving (dataItem.set()) logic...
this.refresh(); //refreshing the grid instance
// reset current cell..
this.current(focusedCell);
setTimeout(function () //refocusing the cell
return function ()
var focusedCell = $("#grid tr[data-uid='" + dataItem.uid + "'] td:nth-child(" + (focusedCellIndex + 1) + ")");
$('#grid').data('kendoGrid').editCell(focusedCell);
(), 200);
【讨论】:
谢谢,我认为我们正在使用第一种方法。_lastFocusedCellIndex
现在一直在工作。但是,例如,如果我在第 3 行编辑单元格 10,它将重新聚焦;如果我再次编辑它,焦点将转到第 1 行的单元格 10。所以,我只需要获取最后一个焦点单元格行的 rowIndex(或 uid)。我尝试使用this._lastFocusedCell = $(element);
扩展您的kendo.ui.Grid.fn.current
版本,然后获取单元格的数据项,但第二次返回网格的第一个数据项。
您不应该使用对 DOM 元素的引用,因为它们会在网格刷新时被替换;我更新了我的答案
非常感谢,即使在 IE 中它也能正常工作 :) 我会为您所做的每条评论或回答 +1,但我还没有足够的声誉 :)
我想我可以因为网格刷新而忘记验证?我正在尝试在 dataSource 模型中进行经典和自定义验证,但似乎没有任何效果。
不确定我理解你在做什么;如果您调用 editCell(cell) 并希望记住该单元格,您也可以显式调用 current(cell)【参考方案2】:
我没有足够的声誉来评论答案,但我要感谢 Lars Hoppner 的回答。它极大地帮助了我解决 Kendo Grids 令人讨厌的刷新导航问题。
我还想为带有水平滚动条的网格添加这一点,您的解决方案仍会导致滚动尽可能向左移动,同时保持最后编辑的单元格处于视图中。为了防止这种不良行为,我做了以下事情:
grid.closeCell();
grid.refresh();
grid.refocusLastEditedCell();
在刷新之前关闭单元格使滚动条保持原位,现在一切正常。希望这可以帮助其他人查看您的答案。
【讨论】:
您还可以保存和恢复具有滚动条的 DOM 元素的 $.scrollTop 和 $.scrollLeft 值(.k-scrollbar-horizontal/vertical 用于常规滚动或 .k-virtual-使用虚拟滚动时可滚动换行) 我还没有尝试过,听起来它会起作用。我唯一担心的是用户可能会看到网格“闪烁”,因为它快速来回滚动。不过还没有确认。以上是关于刷新后剑道网格单元重新聚焦的主要内容,如果未能解决你的问题,请参考以下文章