1

このユーザーは私が尋ねているのと同じ質問をしていたと思いますが、彼の質問の理由が異なっていたので、彼は別の解決策を受け入れました。私は彼が最初に求めていたことをする必要があります:

jqgrid リクエストの自動キャンセル

私の jqGrid には検索ツールバー (列ヘッダーの下、データの上に表示される入力フィールド) があります。ほとんどの列にはドロップダウン (stype=select) があり、その列で使用可能なフィルター オプションが一覧表示され、上部に [すべて] オプションがあります。jqGrid にデータを入力する JSON データで応答するサーバー側のコードは複雑であるため、特にフィルタ基準があまりない場合は、やや遅くなります。これは、ユーザーが「すべて」を選択した場合、結果が表示されるまでに数秒かかる場合があることを意味します。これ自体は問題ありませんが、応答が返される前にユーザーが別のフィルター選択を行った場合、グリッドは既存の要求をキャンセルせず、新しい要求も送信しません。そのため、ユーザーが 2 番目の選択を行ったのある時点で、最初の選択。さらに、フィルターの選択を変更するとグリッドが自動更新されるため、必要なデータを表示するには、選択を別のものに変更し、それが読み込まれるのを待ってから元に戻す必要があります。

これが私がこれまでに試したことです:

$(document).ready(setupGrid);

var currentGridRequest;

function setupGrid() {
    var grid = $("#grid").jqGrid({
        ...
        loadError: function(xhr, status, error) {
            currentGridRequest = undefined;
        },
        loadComplete: function(data) {
            currentGridRequest = undefined;
        },
        loadBeforeSend: function(xhr, settings) {
            if (currentGridRequest !== undefined) {
                currentGridRequest.abort();
            }
            currentGridRequest = xhr;
        }
    });
}

私が抱えている問題は、既に処理中のリクエストがある場合、loadBeforeSend イベントが実際には発生しないことです。イベントのドキュメント ページ ( http://www.trirand.com/jqgridwiki/doku.php?id=wiki:events )から他のイベントを試しました: beforeRequest と jqGridToolbarBeforeSearch はどちらも同じ動作を示します。

処理中のリクエストを中止し、ユーザーの最新の選択に基づいて検索を続行するにはどうすればよいですか? これは jqGrid のバグですか? 私は最初、バージョン 4.2 でこの問題に遭遇しました。この動作に変更はなく、4.4.4 にアップグレードしたばかりです。

jqGrid コードを見ると、jqGrid コード自体を変更しない限り、この動作は避けられないようです。jqGrid は、各リクエストの開始時にフラグ (ts.grid.hDiv.loading) を設定し、最後にそれをクリアします。このフラグが設定されている場合、新しいフィルター条件は送信されず、イベントは発生しません。

また、JSON 応答を変更して要求基準を含めることも検討し、JS コードを記述して、応答を現在の基準選択と比較しました。一致しない場合は、応答を無視し、グリッドにレンダリングしません。jqGrid は 2 番目の一連の基準を SUBMIT することさえしないので、そのオプションは検討の余地がありません (その問題を修正できたとしても、私の現在のアプローチの方が望ましいと思われます)。

4

2 に答える 2

1

私は自分がやりたいことをする方法を見つけました。私はいくつかの場所で jqGrid を使用しています (いくつかのケースでは同じページに複数のグリッドを含む)。そのため、どこからでも呼び出すことができ、現在の要求があるかどうかを管理するための独自のスコープを含む関数に分解しました。グリッドを渡すだけで、必要なすべてのイベント ハンドラーがアタッチされます。これにより、関連するイベントに対して定義した既存のハンドラーが上書きされることに注意してください。

function applyJqgridHandlers(grid) {
    (function(self, undefined) {
        var currentRequest;
        function abortCurrentRequestIfAny() {
            if (currentRequest !== undefined) {
                currentRequest.abort();
            }
        }
        self.clearCurrentRequest = function() {
            abortCurrentRequestIfAny();
            currentRequest = undefined;
        };
        self.setCurrentRequest = function(xhr) {
            abortCurrentRequestIfAny();
            currentRequest = xhr;
        };
    })(grid.currentRequestHolder = {});

    grid.currentRequestHolder.clearCurrentRequest();
    grid.jqGrid('setGridParam', {
        loadError: function(xhr, status, error) {
            grid.currentRequestHolder.clearCurrentRequest();
        },
        loadBeforeSend: function(xhr, settings) {
            grid.currentRequestHolder.setCurrentRequest(xhr);
        },
        loadComplete: function(data) {
            grid.currentRequestHolder.clearCurrentRequest();
        }
    });
    grid.bind('jqGridToolbarBeforeSearch', function() {
        grid.currentRequestHolder.clearCurrentRequest();
        this.grid.hDiv.loading = false;
    });
};

次に、setupGrid() の末尾からこの関数への呼び出しを追加するだけです。

このコードは、公開された jqGrid API の一部ではない ts.grid.hDiv.loading フラグを明示的にクリアするため、このソリューションはかなり脆弱であると考えています。jqGrid の将来のバージョンで引き続き機能するという保証はありません。この問題を解決するためのより良い (壊れにくい) 方法について何か提案があれば、私はすべて耳にします。:)

于 2013-02-15T22:02:15.833 に答える