0

我有一个在运行时轮询数据库并更新 jqGrid 的应用程序。我正在使用 datatype: "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 方法的“位置”和“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);
}
4

2 回答 2

2

我建议你使用

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

保存选择(见这里)。取决于网格的其他选项,您实际上不需要保存和恢复scrollTop位置。我想滚动的问题可能是闪烁的原因。

Moreover it's very important to verify that you use gridview: true option. Moreover the usage of datatype: "local" could be not the best solution at all. Probably you need just use datatype: "json" together with loadonce: true. You can update the data from the server if needed. See here and here for details.

It's very important to understand, that if you change one element (like a cell of the grid) on the page the web browser have to recalculate position of all existing elements. I recommend you to read the article about this. The current implementation of setRowData is so that html content of every cell of the row will be done separately (see here). So if you have n columns in the grid the web browser makes about n times reflow of the whole page. If you you addRowData the whole row will be made at one operation (like here).

The main advantage of the reloading the whole grid (with .setGridParam({ data: localData }); and reloadGrid) is that the whole grid body will be inserted as one operation (see here). So the update of the whole grid follows only one reflow. Of cause there are some other changes (like updating of the pageer), but in general updating of the whole page is much more quickly as it looks like at the first look. It's very important to use gridview: true to have the behavior.

UPDATED: I recommend you additionally to read the answer. Probably it can be helpful for you too.

于 2012-06-15T19:16:35.940 回答
0

I have resolved this by applying my own sorting. My columns are only of sorttype: 'text', therefore this works. As a future feature of the jqGrid, it would be nice if addRowData's position parameter would take in 'sorted', in order to specify that is goes in the sorted order. Please note that EntityId is my id column (a hidden column), and that my column options specify a sortname and sortorder when the grid is initially loaded.

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;
}
于 2012-06-18T15:39:49.870 回答