【问题标题】:Knockout Observable Array with Sorting and Foreach Data-Binding具有排序和 Foreach 数据绑定的 Knockout Observable 数组
【发布时间】:2014-02-11 15:11:23
【问题描述】:

我有一个对象数组,它们连接到一个可淘汰的可观察数组中。我需要对这些数组进行排序,但我遇到了一些令人困惑的行为。

我的第一次尝试涉及在 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);
    });
});

这也有效。而且我什至不需要将数据绑定到计算出的 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);
    });
});

现在,我可以将项目推送到数组并且 DOM 更新,但是数据没有被排序。

我认为这些差异与剔除依赖跟踪有关,以及对可观察数组和其下的本机 JavaScript 数组进行操作之间的差异,但我很难概念化为什么行为会发生变化。我能够让它发挥作用,但我也很好奇什么是最佳实践。

感谢您的帮助。 :)

【问题讨论】:

    标签: arrays sorting knockout.js foreach computed-observable


    【解决方案1】:

    KO 实际上不推荐在视图中使用排序的问题,因为 使用这种方法,observableArray.sort 不会在数组上建立依赖关系,因此绑定不会得到更新。

    所以如果你想让它工作,可以使用

    items.slice(0).sort()
    

    更多详情请查看
    https://github.com/knockout/knockout/issues/1380

    小提琴:http://jsfiddle.net/mbest/6dmAn/

    【讨论】:

      【解决方案2】:

      在您的 JS Fiddle 中,这是因为您的 foreach 与人绑定...而不是 sortedPeople。

      它第一次排序的原因是因为计算运行一次......但不订阅。

      但是,由于对底层数组的某些订阅,当您使用括号时,计算最终会再次运行。

      编辑:

      当你使用括号时,当 observable 被调用时,computed 订阅数组。当订阅的项目发生变化时,重新执行计算。

      【讨论】:

      • 如果您只是订阅了 observable 数组而不是使用计算的数组,可能会更清楚。您基本上是使用计算的订阅。 jsfiddle.net/N9sGY
      • 是的,这解释了最后一个添加项目但未使用的示例。谢谢。任何想法为什么推送/删除功能在第一个小提琴中不起作用,或者为什么添加括号可以修复它?
      • 在第一个小提琴中它基本上是一样的。由于您没有使用括号,因此没有进行订阅。做 people.sort 基本上是短路订阅更改的机制。
      猜你喜欢
      • 2013-08-01
      • 2015-07-02
      • 2016-01-18
      • 2012-09-24
      • 2023-03-21
      • 1970-01-01
      • 2015-04-05
      • 2013-07-17
      • 2014-03-02
      相关资源
      最近更新 更多