Лучший способ разобрать Json? - PullRequest
2 голосов
/ 04 декабря 2010

Я хочу проанализировать данные из 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

Ответы [ 4 ]

2 голосов
/ 04 декабря 2010

Во-первых, ваш 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" каждый раз, когда он получает сообщение "status" в данных. Вы можете добавить чек, чтобы убедиться, что вы без необходимости заново зарегистрируете:

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

1 голос
/ 04 декабря 2010

Вы находите каждый элемент для каждой итерации в цикле.Найдите ячейку и поместите результат в переменную вне цикла.

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

Обратите внимание, что я переименовал некоторые переменные.Вы многократно использовали имена переменных для разных целей, например, для повторного использования переменной data, содержащей строку JSON, для хранения проанализированных данных, и переменной obj, которая содержит результат анализа и содержащий один элемент данных.

Я замечаю, что вы используете this.j в одном месте кода.Это не то же самое, что item[j], но item['j'], что может не соответствовать тому, что предполагалось.

1 голос
/ 04 декабря 2010

Я не уверен, что разбор замедляет вас. Возможно, вы используете много селекторов jQuery для большого количества объектов, что может занять время.

РЕДАКТИРОВАТЬ: увидел @ ответ pointy. Я даже не заметил, что вы делали делегирование событий через атрибуты DOM. Да, это, вероятно, будет работать довольно медленно.

Фактически, использование live делегирования события вместо присвоения события click каждому отдельному элементу, вероятно, будет выполняться еще быстрее. Начните с того, что вместо того, чтобы давать ему событие 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);
});

Это означает, что любой img внутри элемента td.status (да, я создал для вас новое имя класса), который когда-либо существовал, при нажатии будет запускать updateStatus с данными status_obj, хранящимися внутри это.

Некоторые небольшие оптимизации:

  • Укажите имя тега при поиске детей, например, find('span.priority'), поскольку jQuery может затем проходить через только потомки этого имени тега вместо всех потомков
  • Или, на самом деле, присвойте этим детям свои уникальные идентификаторы для поиска, поскольку getElementById почти наверняка будет работать быстрее, чем циклически проходить по детям.
0 голосов
/ 04 декабря 2010

Одна вещь, которую вы можете сделать, чтобы ускорить его, это поместить $("#td_"+i+"_"+j) в свою переменную в начале цикла for:

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

и используйте tdElem вместо $("#td_"+i+"_"+j) везде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...