jqgrid unbind / toggle grid事件

时间:2013-06-28 21:23:19

标签: jqgrid

前言:我正在使用jqGrid 4.1.2(当前版本为4.5.2),因此我提到的一些性能问题可能已经修复。

我正在分析我的JS代码,我注意到jqgrid在我的初始网格绑定期间为每一行触发了afterInsertRow:$('#grid').jqGrid('addRowData', 'ID', data)这又调用了一个调整网格容器DIV大小的函数。由于浏览器重绘事件是一个代价高昂的过程,因此对afterInsertRow的数百次调用最终导致UI出现一些延迟。

我的问题是,取消绑定jqGrid事件的语法是什么?

2 个答案:

答案 0 :(得分:1)

我认为您描述的性能问题的根源如下:

  • 您不使用gridview: true选项
  • 您使用afterInsertRow回调代替使用cellattrrowattr代替。

如果您检查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 answerthis 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});

}