前言:我正在使用jqGrid 4.1.2(当前版本为4.5.2),因此我提到的一些性能问题可能已经修复。
我正在分析我的JS代码,我注意到jqgrid在我的初始网格绑定期间为每一行触发了afterInsertRow:$('#grid').jqGrid('addRowData', 'ID', data)
这又调用了一个调整网格容器DIV大小的函数。由于浏览器重绘事件是一个代价高昂的过程,因此对afterInsertRow的数百次调用最终导致UI出现一些延迟。
我的问题是,取消绑定jqGrid事件的语法是什么?
答案 0 :(得分:1)
我认为您描述的性能问题的根源如下:
gridview: true
选项afterInsertRow
回调代替使用cellattr
,rowattr
代替。如果您检查addJSONData
的源代码的the lines将在填充网格期间使用,您将会看到
if(ts.p.gridview === false ) {
$("#"+$.jgrid.jqID(ts.p.id)+" tbody:first").append(rowData.join(''));
self.triggerHandler("jqGridAfterInsertRow", [idr, rd, cur]);
if(afterInsRow) {ts.p.afterInsertRow.call(ts,idr,rd,cur);}
rowData=[];
}
在while
内部循环遍历网格的所有行。在工具中,jqGrid保存数组rowData
内网格主体的数据。数组rowData
中的项是HTML片段的字符串。
如果您使用gridview: true
,那么所有jqGrid body 将首先保存为数组rowData
中的字符串数组,并使用{{1}创建一个来自数组的字符串循环之后将frin放入体内(参见the line)。
如果您使用rowData.join('')
(它的默认值为!!! ???),则数组gridview: false
将转换为字符串,而行仅会被放置在每一行循环内的页面。我描述了the answer中详述的方法的性能劣势。
不是使用rowData
来自定义某些列的样式,而是应该使用afterInsertRow
代替代码示例(请参阅the answer或this one)。如果您使用cellattr
自定义行的样式,则应使用afterInsertRow
代替(the answer)。如果您需要自定义某些列的包含而不是样式,那么您应该使用custom formatter。如果您遵循上述规则,那么您将不需要使用rowattr
回调,并且填充大网格将非常快。
答案 1 :(得分:0)
因为jqgrid事件被定义为网格属性,所以您可以使用setGridParam
方法重新分配事件参数。将事件属性设置为null
会禁用该事件。
grid_afterInsertRow
不是匿名的,因此可以通过名称轻松引用它。我也使用非匿名函数,因为我不确定对setGridParam
的调用是否会释放任何先前创建的传递给它的匿名函数引用。
function grid_afterInsertRow(rowID, rowData, rowElem) {
// do stuff
}
function toggle_afterInsertRow(isEnabled) {
if(isEnabled) {
$('#grid').jqGrid('setGridParam', {afterInsertRow: grid_afterInsertRow});
} else {
$('#grid').jqGrid('setGridParam', {afterInsertRow: null});
}
}
一些重构提供了上面代码的通用版本
// usage: toggleGridEvent($('#grid'), true, afterInsertRow, grid_afterInsertRow);
function toggleGridEvent($grid, isEnabled, eventName, callback) {
var params = {};
if(isEnabled) {
params[eventName] = callback;
} else {
params[eventName] = null;
}
$grid.jqGrid('setGridParam', {afterInsertRow: grid_afterInsertRow});
}