web-dev-qa-db-ja.com

Knockoutで計算可能な観測可能配列を作成する方法

計算された観測可能な配列を作成する方法を知りたいです。

私のビューモデルには、2つの観測可能な配列があり、単純に両方の配列を組み合わせた計算された観測可能な配列が必要です。

function ViewModel() {
    var self = this;
    self.listA= ko.observableArray([]);
    self.listB = ko.observableArray([]);
    self.masterList= //combine both list A and B
41
Matt Mangold

これにより、2つの配列が結合され、結合されたリストが返されます。ただし、これは計算可能なオブザーバブル配列ではなく(可能かどうかはわかりません)、通常の計算されたオブザーバブルです。

self.masterList = ko.computed(function() {
    return this.listA().concat(this.listB());
}, this);
33
Brian S
self.masterList = ko.observableArray();
ko.computed(function () {
    self.masterList(self.listA().concat(self.listB()));
});

Joe Flateauの精神の答えに似ていますが、この方法はもっと簡単だと思います。

12
tne

私はこれが古い質問であることを知っていますが、そこに私の答えを投げると思いました:

var u = ko.utils.unwrapObservable;

ko.observableArray.fn.filter = function (predicate) {
    var target = this;

    var computed = ko.computed(function () {
        return ko.utils.arrayFilter(target(), predicate);
    });

    var observableArray = new ko.observableArray(u(computed));

    computed.subscribe(function (newValue) { observableArray(newValue); });

    return observableArray;
};
9
Joe Flateau

ObservableArrayは、いくつかのプロパティを備えたオブザーバブルです。したがって、クロージャ内の配列を返す計算されたオブザーバブルは、配列として扱われます。

6
Paolo del Mundo

これが最も効率的なオプションであるかどうかはわかりませんが、それはかなり簡単で、私にとってはうまくいきます。 ko.computedは、次のように監視可能な配列を返します。

self.computedArrayValue = ko.computed(function() {
    var all = ko.observableArray([]);
    ....
    return all(); 
});

コードの実際の例:Html:

<div data-bind="foreach: days">
    <button class="btn btn-default btn-lg day" data-bind="text: $data, click: $root.dayPressed"></button>        
</div> 

ビューモデルのJavascript関数:

self.days = ko.computed(function() {
    var all = ko.observableArray([]);
    var month = self.selectedMonth();   //observable
    var year = self.selectedYear();     //observable
    for (var i = 1; i < 29; i++) {
        all.Push(i);
    }
    if (month == "Feb" && year % 4 == 0) {
        all.Push(29);
    } else if (["Jan","Mar","May","Jul","Aug","Oct","Dec"].find((p) => p == month)) {
        [29,30,31].forEach((i) => all.Push(i));
    } else if (month != "Feb") {
        [29,30].forEach((i) => all.Push(i));                
    }
    return all(); 
});
2