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);

2 回目の試行では、操作に応じて個々の行自体を更新します。

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);
}

これはうまくいきます。選択はリセットされず、ちらつきもありませんが、最後の問題が 1 つあります。行が再ソートされません。

更新された行はそのまま残り、追加された行は正しい場所に配置されません。「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);
}
4

2 に答える 2

2

使用することをお勧めします

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

選択を保存します(ここを参照)。グリッドの他のオプションによっては、実際に保存してscrollTop位置を復元する必要はありません。スクロールの問題がちらつきの原因かもしれないと思います。

さらに、オプションを使用していることを確認することは非常に重要ですgridview: true。さらに、の使用法はdatatype: "local"まったく最善の解決策ではない可能性があります。datatype: "json"おそらく、と一緒に使用する必要がありますloadonce: true。必要に応じて、サーバーからデータを更新できます。詳細については、こちらこちらをご覧ください。

ページ上の1つの要素(グリッドのセルなど)を変更した場合、Webブラウザーは既存のすべての要素の位置を再計算する必要があることを理解することが非常に重要です。これに関する記事を読むことをお勧めします。の現在の実装はsetRowData、行のすべてのセルのhtmlコンテンツが個別に実行されるようにするためのものです(ここを参照)。したがって、グリッドに列がある場合n 、Webブラウザはnページ全体のリフローを約何回か行います。あなたaddRowDataの場合、行全体が1回の操作で作成されます(ここのように)。

グリッド全体.setGridParam({ data: localData });およびreloadGrid)をリロードする主な利点は、グリッド本体全体が1つの操作として挿入されることです(ここを参照)。したがって、グリッド全体の更新は1回のリフローのみに従います。他にもいくつかの変更(ページャーの更新など)がありますが、一般に、ページ全体の更新は、一見したときのようにはるかに高速です。動作をするために使用することは非常に重要gridview: trueです。

更新:回答をさらに読むことをお勧めします。おそらくそれはあなたにも役立つでしょう。

于 2012-06-15T19:16:35.940 に答える
0

私は独自のソートを適用することでこれを解決しました。私の列は sorttype: 'text' のみであるため、これは機能します。jqGrid の将来の機能として、addRowData の position パラメータが「sorted」を取り、それがソートされた順序になることを指定するとよいでしょう。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;
}
于 2012-06-18T15:39:49.870 に答える