eco*_*oic 7 arrays sorting foreach knockout.js computed-observable
我有一个对象数组,它们被连接到一个可挖掘的可观察数组中.我需要对这些数组应用排序,我遇到了一些有点令人困惑的行为.
我的第一次尝试涉及在foreach数据绑定中应用排序.
http://jsfiddle.net/wnfXV/
<ul data-bind="foreach: people.sort(function(l,r) { return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1)})">
这会执行正确的排序,但我无法动态添加/删除数组中的元素并进行DOM更新.
如果我添加一组括号来访问底层JavaScript数组,一切正常.
<ul data-bind="foreach: people().sort(function(l,r) { return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1)})">
根据我发现的一些SO答案,我最终为排序的数组创建了一个计算的observable. http://jsfiddle.net/wnfXV/2/
self.sortedPeople = ko.computed(function() {
return self.people().sort(function(l,r) {
return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1);
});
});
Run Code Online (Sandbox Code Playgroud)
这也有效.而且我甚至不需要数据绑定到计算的observable,因为它立即执行.我可以适当地推送和删除数组项和DOM更新.
但是,如果我将代码更改为:
self.sortedPeople = ko.computed(function() {
return self.people.sort(function(l,r) {
return l.name == r.name ? 0 : (l.name < r.name ? -1 : 1);
});
});
Run Code Online (Sandbox Code Playgroud)
现在,我能够将项目推送到数组并更新DOM,但数据未被排序.
我认为这些差异与敲除依赖性跟踪有关,以及在可观察数组上操作与其下面的本机JavaScript数组之间的区别,但我很难概念化行为正在发生变化的原因.我能够让它发挥作用,但我也很好奇什么是最佳实践.
谢谢你的帮助.:)
小智 1
在你的 JS Fiddle 中,这是因为你的 foreach 与 people 绑定......而不是与 SortedPeople 绑定。
第一次排序的原因是因为计算运行一次......但不订阅。
但是,当您使用括号时,由于底层数组上的某些订阅,计算结果最终会再次运行。
编辑:
当您使用括号时,计算对象将在调用可观察对象时订阅数组。当订阅项发生变化时,重新执行计算。