2010-12-04 5 views
2

私はjsonからデータを解析し、それらをテーブルに置きたいと思っています。私は次のコードを使用していますJsonを解析する最善の方法は?

var obj=$.parseJSON(data); 
data=obj.data; 
totalRecord=obj.totalCount; 
$.each(data,function(i,obj){ 
    for(var j in obj){ 
    switch(j){ 
      case 'priority': 
       $("#td_"+i+"_"+j).find('.priority').val(obj[j]); 
       $("#td_"+i+"_"+j).find('.hidden').val(obj['id']); 
       break; 
      case 'chkbox': 
       $("#td_"+i+"_"+j).find('.chkbox').val(obj['id']); 
       break; 
      case 'status': 
       var val=(this.j)?'active.gif':'deactive.gif'; 
       $("#td_"+i+"_"+j).find('img').attr('src','<?= base_url() ?>assets/grid/images/'+val); 
       $("#td_"+i+"_"+j).find('img').attr('onClick','updateStatus(\''+obj['id']+'\',\''+obj[j]+'\')'); 
       break; 
      case 'edit': 
       $("#td_"+i+"_"+j).find('a').attr('href','index.php/main/edit/'+obj[j]); 
       break; 
      default: 
       $("#td_"+i+"_"+j).html(obj[j]) 
       break; 
      } 
    } 
}); 

しかし、私は少し遅いと思います。同じものを実装する他のより良い方法はありますか?

KrishNik

+0

これは、解析よりむしろ解釈しています。 '$ .parseJSON'はすでに解析を行います。 – Gumbo

+0

テーブルの大きさ(テーブルの行数またはセル数) – Pointy

+0

あなたは直接属性アクセサーを優先して 'attr'を使って実際にドロップするべきです。 'attr'はかなり複雑で、たくさんの関数呼び出しを使います。 –

答えて

1

私はそれがあなたを減速だ解析だか分かりません。多くのオブジェクトで多くのjQueryセレクタを実行している可能性があります。時間がかかることがあります。

編集:ソー・ポーニーの答え。 DOM属性を使ってイベントの委任を行っていることに気付かなかった。 Yeeaah、おそらくかなり遅く走るだろう。

実際、すべての単一要素にclickイベントを割り当てる代わりにliveイベント委任を使用すると、おそらくさらに高速に実行されます。まず、clickイベントを与える代わりに、jQueryのdata関数を使用して、問題のオブジェクトへの参照を要素に与えます。

case 'status': 
    // Note that I switched it to this[j], since I suspect 
    // using this.j was unintentional 
    var val=(this[j])?'active.gif':'deactive.gif'; 
    $('#td_'+i+'_'+j).find('img').attr('src', '<?= base_url() ?>assets/grid/images/'+val). 
     data('status_obj', obj); 

次に、以下のスクリプトをスクリプト全体で1回だけ実行します(明らかにテストされていません)。

$('td.status img').live('click', function() { 
    var obj = $(this).data('status_obj'); 
    updateStatus(obj.id, obj.status); 
}); 

これは、これまで意志が存在するtd.status要素(うん、私はあなたのために新しいクラス名を作った)内部の任意のimgは、クリックされると、その内部に格納されているstatus_objデータをupdateStatusを実行することを意味します。

いくつかの小さな最適化:子供たちを見上げたときに

  • は、例えば、タグ名を指定してくださいfind('span.priority')の場合、jQueryはすべての子ではなくそのタグ名の子のみをループすることができます
  • 実際には、getElementByIdが子供をループするよりも速く実行するため、 。
+0

ありがとうございました実際に私はすべての答えを真としてマークしたいと思います。 – Nick

2

まず、あなたのJSONはある$.parseJSON()にその呼び出しによってを解析され、そして私はそれが遅いないだ賭けます。 であるとすれば、データ構造を解釈してDOMを更新するコードです。

最初にやるべきことは、その内側のループでjQueryの検索スタッシュです。それは少し助けてくれるでしょう:

for (var j in obj) { 
    var cell = $('#td_' + i + '_' + j); 

これでjQueryルックアップを繰り返す代わりに、 "cell"を使うことができます。 (助けてくれないでしょうその、それは何かです。何を処理したいことはクリック(またはものは何でもある(潜在的に大きな)の表にイベントハンドラを設定するための)

、)個々の細胞に、あなたはずっと jQueryの.delegate()機能を使用したほうが良いと思います。

case 'status': 
    $('table').delegate('#td_' + i + '_' + j, 'click', function() { 
     updateStatus(obj['id'], obj[j]); 
    }); 
    break; 

現在のコードは、データ内の「ステータス」メッセージを受け取るたびに、その "onClick"ハンドラを再接続することに注意してください。あなたは不ことを再登録していないことを確認するためのチェックを追加することができます。

case 'status': 
    if (!$('table').data(i + '_' + j)) { 
     $('table').delegate('#td_' + i + '_' + j, 'click', function() { 
     updateStatus(obj['id'], obj[j]); 
     }); 
     $('table').data(i + '_' + j, true); 
    } 
    break; 

どんなにあなたがそれをロールバックする方法、ビッグデータ構造を反復処理し、大きなテーブル内のセルの多くの更新はかなりになることはできません遅い、あなたのCSSなどによると、特に古いブラウザ(IE6)。

for(var j in obj){ 
    var tdElem = $("#td_"+i+"_"+j); 

とどこでもtdElemの代わり$("#td_"+i+"_"+j)を使用します。あなたはそれをスピードアップするために行うことができます

+0

しかし、jQueryのルックアップはこれまでに一度も使用されていないと思います。その参照を一番上に置いておくのは危険ですが、パフォーマンスの違いはありません:/ – Matchu

+0

ああ、男ですが、私は 'attr'を使って' onClick'に気づきませんでした。よく目を覚まし、+ 1' :) – Matchu

+0

まあ私は同意する、@マッチ;セレクタを再利用する "ケース"ブロックが1つまたは2つありますが、実際の遅さはこれらの変更を行うことによって生じると考えられます。 – Pointy

0

一つのことは、あなたのforループの先頭で独自の変数に$("#td_"+i+"_"+j)を置くことです。

1

ループ内のすべての反復の各要素を特定しています。セルを見つけ、結果をループ外の変数に配置します。

var obj = $.parseJSON(data); 
var parsedData = obj.data; 
var totalRecord = obj.totalCount; 
$.each(parsedData, function(i, item) { 
    for(var j in item) { 
    var element = $("#td_"+i+"_"+j); 
    switch(j) { 
     case 'priority': 
     element.find('.priority').val(item[j]); 
     element.find('.hidden').val(item['id']); 
     break; 
     case 'chkbox': 
     element.find('.chkbox').val(item['id']); 
     break; 
     case 'status': 
     var val=(this.j)?'active.gif':'deactive.gif'; 
     element.find('img') 
      .attr('src','<?= base_url() ?>assets/grid/images/'+val) 
      .attr('onClick','updateStatus(\''+item['id']+'\',\''+item[j]+'\')'); 
     break; 
     case 'edit': 
     element.find('a').attr('href','index.php/main/edit/'+item[j]); 
     break; 
     default: 
     element.html(item[j]) 
     break; 
     } 
    } 
    }); 

いくつかの変数の名前を変更しました。解析されたデータを含むJSON文字列を含む変数dataの再利用や、データの単一の項目を含む解析結果を含む変数objのような、変数ごとに変数名を再利用していました。

私はあなたがコードの一点でthis.jを使用していることに気付きました。これは、item[j]ではなく、item['j']と同じですが、これは意図されていない可能性があります。

+0

ありがとうございます。 – Nick

関連する問題