Ani*_*esh -1 ko.observablearray knockout.js durandal
我试图使用knockout observable array在网页中显示大约5000条记录,这需要花费很多时间,
有没有办法处理这个没有分页?
请帮忙..
视图模型中的JS代码,数据来自gridData源中的ajax调用:
groupGrid.prototype.updateGrid = function (gridDataSource, groupGridOptions) {
var self = this;
self.ColumnName(groupGridOption.ColumnNameList); // List of column name available in the data source.
self.gridData(gridDataSource); // taking time while executing this code
self.totalRowCount(self.gridData().length);
self.selectedItems.removeAll();
self.selectedRowCount(0);
};
Run Code Online (Sandbox Code Playgroud)
HTML代码:
<tbody class="ngTBody" data-bind="foreach: gridData">
<tr class="ngdatarow">
<td>
<span class="nameHeader" data-bind="text: $data[$root.ColumnName()[0]], click: $root.gridNameClick" style="cursor: pointer; text-decoration: underline"></span>
</td>
<td>
<span class="displayBlock" data-bind="text: $data[$root.ColumnName()[1]]"></span>
</td>
<td>
<span class="displayBlock" data-bind="text: $data[$root.ColumnName()[3]"></span>
</td>
</tr>
</tbody>
Run Code Online (Sandbox Code Playgroud)
我最近在KO应用程序中一直在摔跤.我刚刚在这里添加了另一个问题的答案,并提出了一些想法:
由此产生的,这是一个小提琴,表明你不需要太多延迟 - 这个演示有3000个项目,并为每个项目生成一个简单的div.根据上面链接的博客文章,这些项目首先在JS数组中构建,然后再转换为observableArray.所以我很确定在这个阶段你看到的性能问题很简单就是KO工作引起的DOM操作.
这并不能解决性能问题,但是如果循环遍历数千个项目并且它使用的模式可以确保在长KO操作之前出现加载微调器,则表明延迟可能是不可避免的,然后隐藏事后呢.所以它至少改善了用户体验.
确保您可以加载微调器:
// Show the spinner immediately...
$("#spinner").show();
// ... by using a timeout.
window.setTimeout(function() {
ko.applyBindings(vm)
}, 1)
Run Code Online (Sandbox Code Playgroud)
隐藏微调器:
<div data-bind="template: {afterRender: hide}">
Run Code Online (Sandbox Code Playgroud)
更新1:
我记得当我使用Opera在机顶盒上工作时,使用DOM操作构建UI时的旧技术.它的速度令人震惊,因此解决方案是将大块HTML存储为字符串,并通过设置innerHTML属性来加载字符串.单页应用的早期版本.无论如何,作为我在这个领域的持续摆弄的一部分,这里是一个jsfiddle,显示通过KO加载的5000个项目,但通过计算的中间html.
换句话说,您从列表中计算HTML,并使用html绑定一次性设置它.我把这个例子设置为5000个项目,几乎是即时的.
巨大的缺点是它严重限制了你在每个项目内绑定所能做的事情......
更新2:
这是一个小提琴,显示了通过数组索引从项目链接回KO视图模型的一些外观.你可以使用这样的结构来做KO支持的大部分工作,但是你会失去一些魔力; 我想你必须自己编写更多代码.
更新3:
这个小提琴显示了一种使用超时将每个项目逐个推入列表的技术.通过在推送操作之间设置超时,DOM逐项更新.因此整体渲染时间仍然很大,但用户可以立即获得反馈:
http://jsfiddle.net/rosenfeld/7TwcV/1/
更新4:
显示上述技术,但通过删除记录做一些有用的事情.
我已经做了很多关于在浏览器中快速生成数据表的研究.使用foreach和text绑定的标准Knockout方法非常慢.简化绑定代码可以实现一些改进,正如我的重复绑定所示.但生成数据表的最快方法是将其组合为JavaScript代码中的字符串,然后将innerHTML其插入到DOM中.我的表绑定是如何做到这一点的一个例子.
在您的情况下,组装数据表的自定义绑定将提供巨大的速度提升.这是我根据你的例子放在一起的自定义绑定:
ko.bindingHandlers.myDataTable = {
init: function () {
return { controlsDescendantBindings: true };
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var output = [],
value = valueAccessor(),
columns = ko.unwrap(value.columns),
column1 = columns[0],
column2 = columns[1],
column3 = columns[2],
data = ko.unwrap(value.data),
dataLength = data.length,
clickFunction = value.click;
output.push('<table><tbody class="ngTBody">');
for (var i = 0; i < dataLength; ++i) {
output.push('<tr class="ngdatarow"><td><span class="nameHeader" data-index="');
output.push(i + '">');
output.push(data[i][column1]);
output.push('</span></td><td><span class="displayBlock">');
output.push(data[i][column2]);
output.push('</span></td><td><span class="displayBlock">');
output.push(data[i][column3]);
output.push('</span></td></tr>');
}
output.push('</tbody></table>');
element.innerHTML = output.join('');
$(element).on('click', 'span.nameHeader', function (event) {
var index = event.target.getAttribute('data-index');
if (index) {
clickFunction(data[index], event);
}
});
}
};
Run Code Online (Sandbox Code Playgroud)
为了比较,我把以下两个小提琴放在一起:
foreach.在我的计算机上渲染表需要2到3秒.我还创建了一个包含绑定和用法的示例,但它需要比上面的示例更长的时间,因为它必须设置5000个事件处理程序而不是一个.clickko.applyBindingsToDescendants
| 归档时间: |
|
| 查看次数: |
1435 次 |
| 最近记录: |