2010-12-04 73 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 2010-12-04 13:14:36

+0

表格有多大(有多少表格行或单元格)? – Pointy 2010-12-04 13:28:16

+0

你应该真的放弃使用`attr`来支持直接属性访问器。 `attr`非常复杂,并且使用大量的函数调用。 – 2010-12-04 13:36:23

回答

1

我不知道这是一个的放慢你失望解析。这可能是因为你在很多对象上运行了很多jQuery选择器,这可能需要一些时间。编辑:看到@ pointy的回答。我甚至没有注意到你通过DOM属性进行事件委托。 Yeeaah,那可能会运行得很慢。

实际上,使用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); 

然后,在整个脚本(显然,未经测试)中仅运行一次。

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

这意味着td.status元素中的任何img(是的,我做了你一个新的类名)曾经存在的意志,一旦被点击,运行updateStatus存储在它里面是status_obj数据。

一些规模较小的优化:

  • 查找儿童在指定标签名称,例如find('span.priority'),因为jQuery只能遍历该标记名称的子项而不是所有子项
  • 或者实际上,可以让这些子项自己的唯一ID进行查找,因为getElementById几乎可以肯定比循环通过子项。
+0

谢谢matchu其实我想把所有的答案都标记为true。 – Nick 2010-12-06 04:27:18

2

首先,你的JSON是解析通过调用$.parseJSON(),我敢打赌这不是。我敢打赌,慢是解释数据结构并更新您的DOM的代码。

您需要做的第一件事是在内部循环中隐藏jQuery查找。这将有所帮助:

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

现在,您可以使用“单元格”,而不是重复该jQuery查找。 (不会帮助多少,但是它的东西。)

对于在(可能很大)表设置事件处理程序,当你要处理哪些点击(或对单个细胞等等),你会最好使用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)。

0

有一两件事可以做,以加快它是把$("#td_"+i+"_"+j)在其自己的变量在你的开始for循环:

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

,并使用tdElem代替$("#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'],这可能不是什么意图。

相关问题