How to create a computed observable array in Knockout
我想知道如何创建一个可计算的可观察数组。
在我的视图模型中,我有2个可观察的数组,并且我想有一个计算的可观察的数组,它是两个数组的简单组合。
1 2 3 4 5 | function ViewModel() { var self = this; self.listA= ko.observableArray([]); self.listB = ko.observableArray([]); self.masterList= //combine both list A and B |
这将合并两个数组并返回合并的列表。但是,它不是一个可计算的可观察数组(甚至不知道这是否可能),而是一个常规的可计算的可观察数组。
1 2 3 | self.masterList = ko.computed(function() { return this.listA().concat(this.listB()); }, this); |
1 2 3 4 | self.masterList = ko.observableArray(); ko.computed(function () { self.masterList(self.listA().concat(self.listB())); }); |
本质上类似于Joe Flateau的回答,但我想认为这种方法更简单。
我知道这是一个古老的问题,但是我想把答案扔在那里:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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; }; |
observableArray只是一个具有更多属性的可观察对象。因此,在闭包中返回数组的计算可观察值将被视为数组。
我不确定这是否是最有效的选择-但这很简单并且对我有用。 ko.computed返回一个可观察的数组,如下所示:
1 2 3 4 5 | self.computedArrayValue = ko.computed(function() { var all = ko.observableArray([]); .... return all(); }); |
该代码的工作示例:
HTML:
1 | <button class="btn btn-default btn-lg day" data-bind="text: $data, click: $root.dayPressed"></button> |
视图模型上的Javascript函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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(); }); |