2012-05-05 4 views

答えて

15


私は、このメソッドを使用します。私はその質問が他の多くのユーザーにとって興味深いと思う。だから+1。

共通ブラウザの独立したケースでsetIntervalの継ぎ目が私の最善の方法です。変数の中にsetIntervalの結果を保存して、clearIntervalを使用して停止させる必要があります。

もう一つの小さな改善がtriggerの2番目のパラメータとして(詳細はthe answerを参照)[{current:true}]の使用次のようになります。

var $grid = jQuery("#list1"), timer; 

timer = setInterval(function() { 
    $grid.trigger('reloadGrid', [{current: true}]); 
}, 5000); 

それは、グリッドのリロード時に選択を保存します。

多くの新しいWebブラウザでは、現在WebSocketがサポートされています。したがって、Webブラウザがサポートしている場合は、その方法を使用する方が良いでしょう。この方法では、サーバー上でデータが変更されず、サーバーの永続的なプールが行われない場合に備え、不要なグリッドの再読み込みをスキップできます。

さらに一般的なやり方は私にとっても非常に興味深いようです。グリッドデータの最後の変更のタイムスタンプを使用すると、データが変更されているかどうかを確認できます。その目的のために、サーバ上でETagまたは何か一般的な追加の方法を使うことができます。

jqGridを埋めるjQuery.ajaxの現在successコールバックは、あなたがにサーバの応答を変更beforeProcessingコールバックを実装するために使用することができますが、それはあなたが(それがでxhr.statusだろうjqXHR.satus値に基づいてをリフレッシュjqGridを停止することができますではありません現在のjqGridコード)。 jqGridのコードのthe lineを少し変更すると、サーバー上のデータが変更されていない場合にjqGridの最新表示を停止することができます。 "notmodified"の場合はtextStatusst)のコードを、304の場合はjqXHR.satus(現在のjqGridコードのxhr.status)をテストできます。シナリオを使用する場合は、prmNames: { nd:null }オプションを使用し、ETagCache-Control: private, max-age=0と設定することが重要です(詳細についてはhere,hereおよびhereを参照)。

UPDATED:前回の提案に基づいてデモプロジェクトを作成しようとしましたが、上記のように簡単ではないことがわかりました。それにもかかわらず、私はそれを働かせました。難しかったのは、jQuery.ajaxのサーバーレスポンスから304コードが見えないからです。その理由は、XMLHttpRequest specification

For 304 Not Modified responses that are a result of a user agent generated conditional request the user agent must act as if the server gave a 200 OK response with the appropriate content. The user agent must allow author request headers to override automatic cache validation (e.g. If-None-Match or If-Modified-Since), in which case 304 Not Modified responses must be passed through.

で、次の場所だったので、1 304は、サーバ応答からを変更していない代わり$.ajaxsuccessハンドラの内部で200 OK状況を見ています。 XMLHttpRequestはすべてのHTTPヘッダーを含むキャッシュからの完全な応答を返すようです。そこで私はキャッシュされたデータの分析を変更して、最後のHTTPレスポンスから新しいjqGridパラメータとしてETagを保存し、保存されたデータで新しいレスポンスのETagをテストすることにしました。

PHPを使用していることがわかりました(私は使用しません:-()。)しかし、私はPHPコードを読んで理解することができます。 PHPで同じことを実施することができるであろう。

を今、私は私が何をしたかを説明します。まず第一に、私は

if ($.isFunction(ts.p.beforeProcessing)) { 
    if (ts.p.beforeProcessing.call(ts, data, st, xhr) === false) { 
     endReq(); 
     return; 
    } 
} 

if ($.isFunction(ts.p.beforeProcessing)) { 
    ts.p.beforeProcessing.call(ts, data, st, xhr); 
} 

からbeforeProcessingコールバックを使用しjqGridのソースコードのthe linesを修正しました

beforeProcessingからfalseを返して、データの更新をスキップして、データの処理をスキップすることができます。ライン$("#isProcessed").text("Processed");またはライン$("#isProcessed").text("Processing skipped!!!");は、私がいることを視覚的にデータを示すために使用されるのdiv内"Processed"または"Processing skipped!!!"テキストを設定

beforeProcessing: function (data, status, jqXHR) { 
    var currentETag = jqXHR.getResponseHeader("ETag"), $this = $(this), 
     eTagOfGridData = $this.jqGrid('getGridParam', "eTagOfGridData"); 
    if (currentETag === eTagOfGridData) { 
     $("#isProcessed").text("Processing skipped!!!"); 
     return false; 
    } 
    $this.jqGrid('setGridParam', { eTagOfGridData: currentETag }); 
    $("#isProcessed").text("Processed"); 
} 

:私は、デモで使用beforeProcessingの実装は、使用ETagに基づいていますグリッドを埋めるためにサーバーが使用されました。

デモで私は同じデータを持つ2つのグリッドを表示します。私はデータの編集に使用する最初のグリッドです。 2番目のグリッドは、毎秒サーバーからデータを取得します。

GET http://localhost:34336/Home/DynamicGridData?search=false&rows=10&page=1&sidx=Id&sord=desc&filters= HTTP/1.1 
X-Requested-With: XMLHttpRequest 
Accept: application/json, text/javascript, */*; q=0.01 
Referer: http://localhost:34336/ 
Accept-Language: de-DE 
Accept-Encoding: gzip, deflate 
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; LEN2) 
Host: localhost:34336 
If-None-Match: D5k+rkf3T7SDQl8b4/Y1aQ== 
Connection: Keep-Alive 

HTTPレスポンス:

HTTP/1.1 304 Not Modified 
Server: ASP.NET Development Server/10.0.0.0 
Date: Sun, 06 May 2012 19:44:36 GMT 
X-AspNet-Version: 4.0.30319 
X-AspNetMvc-Version: 2.0 
Cache-Control: private, max-age=0 
ETag: D5k+rkf3T7SDQl8b4/Y1aQ== 
Connection: Close 

のでデータは、サーバから転送されませんデータがサーバー上で変更されていない場合はHTTPトラフィックは、次の

HTTPリクエストとして見えますデータが変更されない場合データが変更された場合、HTTPヘッダーはHTTP/1.1 200 OKで開始され、データ自体のページとともに新しい変更済みデータのETagが含まれます。

ナビゲータの「更新」ボタンを使用してグリッドのデータを手動でリフレッシュするか、または毎秒$grid1.trigger('reloadGrid', [{ current: true}]);を実行する「自動リフレッシュ開始」ボタンを使用してリフレッシュできます。私はカラーボックスとページの下部にある最も重要な部分をマークし

enter image description here

のようにページが見えます。 loadui: "disable"オプションが1つの場合、サーバーをプルする際にグリッドに変更が全く表示されません。非常に短い時間の間、 "Loading ..." divと表示されるというオプションをコメントした場合、グリッドが含まれていないと、が点滅します。

「Autorefreshing」の開始後いずれか一方が第1グリッド内のいくつかの行を変更したい場合、第2のグリッドは第一の意志で変更するenter image description here

以下

ような大部分の画像が表示されますテキストを"Processing skipped!!!"にもう一度変更すると、"Processed"のテキストを参照してください。

サーバー側で対応するコードは(私はASP.NET MVCを使用)、主にある以下の

public JsonResult DynamicGridData(string sidx, string sord, int page, int rows, 
            bool search, string filters) 
{ 
    Response.Cache.SetCacheability (HttpCacheability.ServerAndPrivate); 
    Response.Cache.SetMaxAge (new TimeSpan (0)); 

    var serializer = new JavaScriptSerializer(); 
    ... - do all the work and fill object var result with the data 

    // calculate MD5 from the returned data and use it as ETag 
    var str = serializer.Serialize (result); 
    byte[] inputBytes = Encoding.ASCII.GetBytes(str); 
    byte[] hash = MD5.Create().ComputeHash(inputBytes); 
    string newETag = Convert.ToBase64String (hash); 
    Response.Cache.SetETag (newETag); 
    // compare ETag of the data which already has the client with ETag of response 
    string incomingEtag = Request.Headers["If-None-Match"]; 
    if (String.Compare (incomingEtag, newETag, StringComparison.Ordinal) == 0) { 
     // we don't need return the data which the client already have 
     Response.SuppressContent = true; 
     Response.StatusCode = (int)HttpStatusCode.NotModified; 
     return null; 
    } 

    return Json (result, JsonRequestBehavior.AllowGet); 
} 

私は、コードの主なアイデアだけでなく、ASPを使用する人々のためにも明らかであろうことを願っています.NET MVC。

hereプロジェクトをダウンロードできます。

更新:私はbeforeProcessingfalse値を返すことにより、サーバーの応答の処理を破ることができるようにthe feature requestを掲載。対応する変更は、メインのjqGridコードに既に含まれています(hereを参照)。したがって、次のリリースのjqGridにはそれが含まれます。

+0

x秒ごとにグリッドをリロードするのではなく、行に直接「書き込む」ことはできませんか? – Bertaud

+0

@Bertaud:申し訳ありませんが、あなたは何を意味するのか分かりません。どのようにしても、私はあなたがいつもjqGridの 'gridview:true'オプションを使うと思います。グリッド本体全体は、テーブル本体に 'innerHTML'を設定することで、1回の操作で更新されます。 jqGrid *の多くの行やセルを個別に変更する場合は、グリッド全体をリロードする際に時間がかかることがあります。さらに、いくつかの行が追加または削除された場合、ページャーも変更する必要があります。グリッドの再読み込みは私にとって最善の方法です。 – Oleg

+0

@Bertaud:ページ上の* one *要素の変更は、ページ上の**すべての**他の既存の要素の位置の再計算(リフロー)に従うことを理解する必要があります。したがって、ページの変更を減らすことは、ページのパフォーマンスを向上させる上で最も重要になります。たとえば、ブラウザのリフローを最小限に抑える方法については、[こちら](https://developers.google.com/speed/articles/reflow)をご覧ください。 – Oleg

関連する問題