Создание HTML-таблицы на лету с помощью jQuery

Что такое NullPointerException?

Хорошим местом для начала является JavaDocs . Они охватывают это:

Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  • Вызов метода экземпляра нулевого объекта.
  • Доступ или изменение поля нулевого объекта.
  • Выполнение длины null, как если бы это был массив.
  • Доступ или изменение слотов с нулевым значением, как если бы это был массив.
  • Бросать нуль, как если бы это было значение Throwable.

Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.

blockquote>

Также, если вы попытаетесь использовать нулевую ссылку с synchronized, который также выдаст это исключение, за JLS :

SynchronizedStatement:
    synchronized ( Expression ) Block
  • В противном случае, если значение выражения равно null, NullPointerException.
blockquote>

Как это исправить?

Итак, у вас есть NullPointerException. Как вы это исправите? Возьмем простой пример, который выдает NullPointerException:

public class Printer {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print();
    }
}

Идентифицирует нулевые значения

. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

Здесь мы видим, что исключение выбрано в строке 13 (в методе printString). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, что s имеет значение null, а вызов метода length на него вызывает исключение. Мы видим, что программа перестает бросать исключение, когда s.length() удаляется из метода.

Трассировка, где эти значения взяты из

Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что s передается с printString(name) в методе print(), а this.name - null.

Трассировка, где эти значения должны быть установлены

Где установлен this.name? В методе setName(String). С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. ​​

Этого достаточно, чтобы дать нам решение: добавить вызов printer.setName() перед вызовом printer.print().

Другие исправления

Переменная может иметь значение по умолчанию setName может помешать ему установить значение null):

private String name = "";

Либо метод print, либо printString может проверить значение null например:

printString((name == null) ? "" : name);

Или вы можете создать класс, чтобы name всегда имел ненулевое значение :

public class Printer {
    private final String name;

    public Printer(String name) {
        this.name = Objects.requireNonNull(name);
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer("123");
        printer.print();
    }
}

См. также:

Я все еще не могу найти проблему

Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).

21
задан Peter Mortensen 3 February 2011 в 19:03
поделиться

8 ответов

Вы в основном хотите настроить свои циклы, таким образом, они уступают другим потокам время от времени. Вот некоторый пример кода от эта статья о теме рабочих интенсивных действий ЦП, не замораживая Ваш UI:

function doSomething (progressFn [, additional arguments]) {
    // Initialize a few things here...
    (function () {
        // Do a little bit of work here...
        if (continuation condition) {
            // Inform the application of the progress
            progressFn(value, total);
            // Process next chunk
            setTimeout(arguments.callee, 0);
        }
    })();
}

До упрощения производства HTML в Вашем сценарии при использовании jQuery Вы могли бы дать мой Простые Шаблоны плагин попытка. Это убирает процесс путем сокращения решительно на количестве конкатенаций, которые необходимо сделать. Это работает вполне прилично, также после того, как я недавно сделал некоторый рефакторинг, который привел к довольно большому увеличение скорости . Вот пример (не делая весь из работы для Вас!):

var t = eval('(' + request + ')') ;
var templates = {
    tr : '<tr>#{row}</tr>',
    th : '<th>#{header}</th>',
    td : '<td>#{cell}</td>'
};
var table = '<table><thead><tr>';
$.each(t.hdrs, function (key, val) {
    table += $.tmpl(templates.th, {header: val});
});
...
26
ответ дан 29 November 2019 в 20:35
поделиться

Я использовал JTemplates для выполнения то, что Вы описываете. У Dave Ward есть пример на его блоге здесь . Основное преимущество JTemplates - то, что Ваш HTML не ткут в Ваш JavaScript. Вы пишете шаблон и вызываете две функции для имения сборки jTemplate HTML из шаблона и json.

11
ответ дан 29 November 2019 в 20:35
поделиться

То, что Вы делаете, создает строку, и затем анализирует все это сразу на вставку. Что относительно того, чтобы создать фактический элемент таблицы (т.е. $("<table>")), и затем добавить каждую строку к нему в свою очередь? К тому времени, когда Вы на самом деле вставляете его в страницу, узлы DOM будут все созданы, таким образом, это не должен быть столь же большой хит.

3
ответ дан 29 November 2019 в 20:35
поделиться

Используя innerHTML может определенно быть намного быстрее, чем использование HTML-to-DOM-ifier jQuery, который использует innerHTML, но делает большую обработку на исходных данных.

я предложил бы проверить chain.js как способ быстро пристроить таблицы и другие структуры данных повторения от объектов JavaScript. Это - действительно легкий, умный плагин привязки данных для jQuery.

3
ответ дан 29 November 2019 в 20:35
поделиться

Для начала, выезд flydom и это являются вариантами, они помогут чрезвычайно. Вы могли возможно дать больше контекста? Если это не находится в onload и просто вставлено на странице, просто обернув все это в $ (функция () {/* кодируют */}), вероятно, очистит все, с чем у Вас есть проблемы. Встроенный JS сразу выполняется, что означает что цикл для таблицы. onload является событием и по существу 'отсоединился'.

0
ответ дан 29 November 2019 в 20:35
поделиться

Мой опыт состоял в том, что существует две дискретных задержки. Каждый связывает все те строки вместе. Другой, когда браузер на самом деле пытается представить строку. Как правило, это - IE, который испытывает большинство затруднений с замораживаниями UI, частично потому что это намного медленнее в под управлением JavaScript. Это должно поправиться в IE8.

то, Что я предложил бы в Вашем случае, повреждает операцию в шаги. Скажите для 100 таблиц строки, Вы производите допустимые 10 таблиц строки сначала. Тогда Вы выводите это на экран и используете setTimeout для возврата управления браузеру, таким образом, UI прекращает блокироваться. Когда setTimeout возвращается, Вы делаете следующие 10 строк, и т.д.

, Создание таблицы с помощью DOM является, конечно, "инструментом для очистки", как сказали другие. Однако существует крутая цена для оплаты с точки зрения производительности. Посмотрите превосходное статья quirksmode об этом предмете, который имеет некоторые сравнительные тесты, которые можно выполнить сами.

, Короче говоря, innerHTML очень, намного быстрее, чем DOM, даже на современных механизмах JS.

0
ответ дан 29 November 2019 в 20:35
поделиться

Ищите сеть JavaScript и StringBuilder. Как только у Вас есть строитель последовательности JavaScript, удостоверяются, что Вы используете .append метод для каждой связи. Таким образом, Вы не хотите иметь любой + связи. После этого ищите JavaScript и replacehtml. Используйте эту функцию вместо innerHTML.

0
ответ дан 29 November 2019 в 20:35
поделиться

Вы могли вставить таблицу в DOM поразрядно. Честно я не совсем уверен, поможет ли это с Вашей проблемой, но это стоит попытки. Я сделал бы это примерно как это (непротестированный код, мог быть, совершенствовали еще немного):

$("#result").append('<table id="myTable" cellspacing=0 cellpadding=2 border=1></table>');
$('#myTable').append('<thead><tr></tr></thead>');
$('#myTable').append('<tbody></tbody>');

for (var i = 0; i < t.hdrs.length; i++) { 
    $('#myTable thead tr').append('<th>'+header+'</th>');
}

for (var i = 0; i < t.data.length; i++) { 
 myTr =    '<tr>';
 for (var j = 0; j < t.hdrs.length; j++) { 
  myTr += '<td>';
  if (t.data[i][t.hdrs[j]] == "") { 
   myTr += "&nbsp;" ; 
  }
  else { 
   myTr += t.data[i][t.hdrs[j]] ; 
  }
  myTr += "</td>";
  }
 myTr +=    "</tr>";
 $('#myTable tbody').append(myTr);
}

$("#PleaseWaitGraphic").addClass("hide");
$(".rslt").removeClass("hide") ;
-2
ответ дан 29 November 2019 в 20:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: