与.sort绑定时,KO ObservableArray更新中断

时间:2013-09-10 22:14:41

标签: javascript knockout.js

我正在对标记中的ObservableArray进行排序,但出于某种原因,当我将新对象推送到页面ObservableArray时,这不会更新。

//store.get('pages') returns an ObservableArray

<!-- ko foreach:store.get('pages').sort(function (l , r ) { return l.pageNumber() < r.pageNumber() ? -1 : 1}) -->
    <markup/>
<!--/ko-->

但是,当我删除sort调用时,它会很好地捕获数组更改。 像这样,

//works fine,  updates when item pushed to observableArray
<!-- ko foreach:store.get('pages') -->
    <markup/>
<!--/ko-->

想要一个简单的解决方法吗?

编辑

尝试使用valueHasMutated(),也不会强制更新。

解决方法:   我最终将sort调用移动到了observableArray的订阅中,现在看起来工作正常,但不确定为什么。

1 个答案:

答案 0 :(得分:1)

store.get返回observableArraystore.get(...).sort(...)返回一个数组。你有效地制作了这样的单向绑定:

<div data-bind="foreach: ['foo', 'bar']"></div>

此外,虽然您绑定了一个函数调用的返回值,但对我而言,它具有代码味道,您将业务逻辑与视图逻辑耦合。你有这样的事情:

// View
<div data-bind="foreach: $root.get()"></div>

// Javascript
function ViewModel () {
    var self = this;
    self.get = function () {
        return ko.observableArray();
    };
}

它有效,但从你的角度来看,目前还不清楚你在做什么。我认为更好的解决方案是:

// View
<div data-bind="foreach: stores"></div>

// Javascript
function ViewModel () {
    var self = this;
    self.stores = ko.observableArray();
    self.get = function () {
        var arr = ["foo", "bar"];
        stores(arr.sort(...));// When you do this, KO updates the foreach binding this is bound to
        return stores;// not that you need to, you can access it from the viewModel.
    };
}

很高兴您找到了解决方法,但花了一分钟时间计划出HTML绑定结构。这是我在创建新视图时开始的第一个地方,它驱动了我构建ViewModel的方式。