0

このようにマークアップでソート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-->

ただし、並べ替え呼び出しを削除すると、配列の変更がうまくキャッチされます。そのようです、

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

簡単な回避策のアイデアはありますか?

編集

valueHasMutated() を使用してみましたが、更新も強制しません。

回避策: 並べ替え呼び出しを observableArray のサブスクリプションに移動することになりましたが、現在は正常に機能しているようですが、理由はわかりません。

4

1 に答える 1

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 をどのように構築するかを決定します。

于 2013-09-10T23:04:13.450 に答える