How to create a computed observable array in Knockout

后端 未结 5 1098
小蘑菇
小蘑菇 2021-01-07 16:25

I would like to know how to create a computed observable array.

In my view model, I have 2 observable arrays, and I would like to have a computed observable array

相关标签:
5条回答
  • 2021-01-07 16:33

    This will combine the two arrays and return the combined list. However, it is not a computed observable array (don't know if that is even possible), but a regular computed observable.

    self.masterList = ko.computed(function() {
        return this.listA().concat(this.listB());
    }, this);
    
    0 讨论(0)
  • 2021-01-07 16:34

    I'm not sure if this is the most efficient option - but it is fairly simple and works for me. The ko.computed returns an observable array as below:

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

    A working example of the code: Html:

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

    Javascript function on the view model:

    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(); 
    });
    
    0 讨论(0)
  • 2021-01-07 16:37

    I know this is an old question but I thought I'd throw my answer in there:

    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;
    };
    
    0 讨论(0)
  • 2021-01-07 16:51
    self.masterList = ko.observableArray();
    ko.computed(function () {
        self.masterList(self.listA().concat(self.listB()));
    });
    

    Similar to Joe Flateau's answer in spirit, but I like to think this method is simpler.

    0 讨论(0)
  • 2021-01-07 16:57

    An observableArray is just an observable with a few more properties. Therefore, a computed observable that returns an array in the closure will be treated as an array.

    0 讨论(0)
提交回复
热议问题