我刚刚开始使用 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
KnockoutobservableArray
对象的方法非常慢。
这是我的模板:
<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 本身支持),这个模板引擎将在 3 秒多一点内绘制大约 400 行。这似乎是最好的方法,缺少一种可以在滚动时动态加载更多数据的解决方案。