jqGrid:执行排序而不刷新整个网格

时间:2012-06-15 15:23:17

标签: jquery jqgrid

我有一个应用程序轮询数据库并在运行时更新jqGrid。我正在使用数据类型:“local”,以便能够在客户端操作数据,而无需重新加载所有内容。

我的第一次尝试更新了数据本身,更新了网格数据并重新加载。这很有效,但是在IE8(不幸的是我们的主要目标)中,当滚动条重置到其原始位置时会出现闪烁。还有一个问题是选择被重置,但那个选项可以解析。

grid.setGridParam({ data: localData });
var scrollPosition = grid.closest(".ui-jqgrid-bdiv").scrollTop();
grid.trigger('reloadGrid');
grid.closest(".ui-jqgrid-bdiv").scrollTop(scrollPosition);

我的第二次尝试根据操作自行更新各行。

if (toUpdate) { /* Not auto sorted */
   grid.jqGrid('setRowData', entityUpdate.EntityId, entityUpdate);
}
else if(toAdd) { /* Not auto sorted */
   grid.jqGrid('addRowData', entityUpdate.EntityId, entityUpdate);
}
else if(toDelete) {
   grid.jqGrid('delRowData', entityUpdate.EntityId);
}

这很有效。选择不会重置,没有闪烁,但最后一个问题是:没有使用行。

任何更新的行都会保留在原来的位置,并且添加的任何行都不会出现在正确的位置。我可以使用“sortGrid”方法,但后来我们又回来刷新整个网格。我可以使用addRowData方法的“position”和“srcrowid”参数的组合,以便将它放在正确的位置,但我必须确切地知道放在哪里。有没有办法使用内置的排序算法来找到它的位置?代码将成为:

if (toUpdate) { 
   grid.jqGrid('delRowData', entityUpdate.EntityId);
   grid.jqGrid('addRowData', entityUpdate.EntityId, entityUpdate, ?, ?);
}
else if(toAdd) {
   grid.jqGrid('addRowData', entityUpdate.EntityId, entityUpdate, ?, ?);
}
else if(toDelete) {
   grid.jqGrid('delRowData', entityUpdate.EntityId);
}

2 个答案:

答案 0 :(得分:2)

我建议你使用

grid.trigger('reloadGrid', [{current:true}]);

保存选择(请参阅here)。依赖于网格的其他选项,您无需真正需要保存并恢复scrollTop位置。我认为滚动的问题可能是闪烁的原因。

此外,验证您使用gridview: true选项非常重要。此外,datatype: "local"的使用可能不是最好的解决方案。您可能只需将datatype: "json"loadonce: true一起使用即可。如果需要,您可以从服务器更新数据。有关详细信息,请参阅herehere

理解非常重要的是,如果您在页面上更改一个元素(如网格的单元格),则Web浏览器必须重新计算所有现有位置元素。我建议你阅读the articlesetRowData的当前实现是这样行的每个单元格的html内容将单独完成(参见here)。因此,如果网格中有n列,则网络浏览器会对整个页面进行约n次重排。如果您addRowData,整行将在一个操作(例如here)进行。

重新加载整个网格(使用.setGridParam({ data: localData });reloadGrid)的主要优点是整个网格主体将被插入一个操作(请参阅here)。因此,整个网格的更新仅遵循一次重排。原因还有其他一些变化(比如更新寻呼机),但总的来说,整个页面的更新速度要快得多,因为它看起来像第一眼看上去的样子。使用gridview: true来表达行为非常重要。

更新:我建议您另外阅读the answer。可能它对你也有帮助。

答案 1 :(得分:0)

我通过应用自己的排序解决了这个问题。我的列只是sorttype:'text',因此这有效。作为jqGrid的未来特性,如果addRowData的位置参数将采用“已排序”,以便指定以排序顺序进行,那将是很好的。请注意,EntityId是我的id列(隐藏列),并且我的列选项在最初加载网格时指定了sortname和sortorder。

function updateGrid(grid, entities) {
    var sortName = grid.jqGrid('getGridParam', 'sortname');
    var sortOrder = grid.jqGrid('getGridParam', 'sortorder');
    var rowData = grid.jqGrid('getRowData');
    for (var i = 0; i < entities.length; i++) {
        var entityUpdate = entities[i];
        if (shouldBeInGrid) {
             var currentRow = grid.jqGrid('getRowData', entityUpdate.EntityId);
            //The row exists, update it.
            if (!isEmptyRow(currentRow)) {
                if (currentRow[sortName] == entityUpdate[sortName]) {
                    //The column hasn't changed, just update the values.
                    grid.jqGrid('setRowData', entityUpdate.EntityId, entityUpdate);
                }
                else {
                    grid.jqGrid('delRowData', entityUpdate.EntityId);
                    addRowSorted(grid, rowData, sortName, sortOrder, entityUpdate);
                }
            }
            //The row does not exist, add it.
            else {
                 addRowSorted(grid, rowData, sortName, sortOrder, entityUpdate);
            }
        }
        //The row should not be in the table, delete it if it doesn't exist.
        else {
            grid.jqGrid('delRowData', entityUpdate.EntityId);
        }
    }
}

function addRowSorted(grid, allData, sortName, sortOrder, toAdd) {
    for (var i = 0; i < allData.length; i++) {
        var valueFromGrid = allData[i][sortName].toLowerCase();
        var valueToVerify = toAdd[sortName].toLowerCase();
        var srcId = allData[i][entityIdColumnId];
        if (sortOrder == "desc" && valueFromGrid < valueToVerify) {
            grid.jqGrid('addRowData', toAdd.EntityId, toAdd, 'before', srcId);
            return;
        }
        else if (sortOrder == "asc" && valueFromGrid > valueToVerify) {
            grid.jqGrid('addRowData', toAdd.EntityId, toAdd, 'before', srcId);
            return;
        }
    }
    //The data is empty or it should be last, add it at the end.
    grid.jqGrid('addRowData', toAdd.EntityId, toAdd, 'last');

}


function isEmptyRow(data) {
    for (var property in data) {
        return false;
    }
    return true;
}