我刚刚开始使用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
敲除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本身提供了支持),并且该模板引擎将在3秒钟内绘制约400行。这似乎是最好的方法,缺少一种解决方案,该解决方案可以在滚动时动态加载更多数据。