Я только начинаю работать с Knockout.js (всегда хотел попробовать, но теперь у меня наконец-то есть оправдание!). Однако при привязке таблицы к относительно небольшому набору таблиц у меня возникают серьезные проблемы с производительностью. данные (около 400 строк или около того).
В моей модели есть такой код:
this.projects = ko.observableArray( [] ); //Bind to empty array at startup
this.loadData = function (data) //Called when AJAX method returns
{
for(var i = 0; i < data.length; i++)
{
this.projects.push(new ResultRow(data[i])); //<-- Bottleneck!
}
};
Проблема в том, что forцикл выше занимает около 30 секунд с примерно 400 строками. Однако, если я изменю код на:
this.loadData = function (data)
{
var testArray = []; //<-- Plain ol' Javascript array
for(var i = 0; i < data.length; i++)
{
testArray.push(new ResultRow(data[i]));
}
};
Затем forцикл завершается в мгновение ока. Другими словами, pushметод объекта Knockout observableArrayневероятно медленный.
Вот мой шаблон:
<tbody data-bind="foreach: projects">
<tr>
<td data-bind="text: code"></td>
<td><a data-bind="projlink: key, text: projname"></td>
<td data-bind="text: request"></td>
<td data-bind="text: stage"></td>
<td data-bind="text: type"></td>
<td data-bind="text: launch"></td>
<td><a data-bind="mailto: ownerEmail, text: owner"></a></td>
</tr>
</tbody>
Мои вопросы:
- Это правильный способ привязать мои данные (которые поступают из метода AJAX) к наблюдаемой коллекции?
- Я ожидаю
push, что каждый раз, когда я его вызываю, выполняется тяжелая перерасчет, например, возможно, перестройка связанных объектов DOM. Есть ли способ отложить этот пересчет или, возможно, отправить все мои элементы сразу?
При необходимости я могу добавить больше кода, но я почти уверен, что это то, что нужно. По большей части я просто следил за учебниками Knockout с сайта.
ОБНОВИТЬ:
Следуя приведенному ниже совету, я обновил свой код:
this.loadData = function (data)
{
var mappedData = $.map(data, function (item) { return new ResultRow(item) });
this.projects(mappedData);
};
Однако this.projects()для 400 строк по-прежнему требуется около 10 секунд. Признаюсь, я не уверен, насколько быстро это было бы без Knockout (просто добавление строк через DOM), но мне кажется, что это было бы намного быстрее, чем 10 секунд.
ОБНОВЛЕНИЕ 2:
Следуя другим советам, приведенным ниже, я попробовал jQuery.tmpl (который изначально поддерживается KnockOut), и этот шаблонизатор отрисует около 400 строк всего за 3 секунды. Это кажется лучшим подходом, если не считать решения, которое динамически загружало бы больше данных при прокрутке.