在knockout计算访问器上订阅arrayChange

时间:2014-05-28 16:21:21

标签: javascript arrays knockout.js

我有一个案例,我需要监听计算机的数组更改,这只是返回一个observable的过滤值。 但是,我确实需要有完整的更改列表,因为 .subscribe(function(changes){},null,'arrayChange')可以在 observableArray 上执行。

我的理解是 arrayChange 在计算值的情况下不起作用,因为它可能会重新创建一个新数组,所以没有特定的列表更改。

有关完整示例,请参阅http://jsfiddle.net/darknessm0404/A6D8u/1/

// The following does not work, but I'd like it
computedTest.subscribe(function(changesList){
    console.log('COMPUTED subscription : arrayChange');
}, null, 'arrayChange');

我似乎实现我想要的唯一方法是创建另一个可观察的数组,根据更改将推送/删除,因此我可以使'arrayChange'方法有效。

我的想法的完整示例:

this.events.listFiltered = ko.observableArray().extend({ rateLimit: 0 });
this.events.listFiltered_Worker = ko.computed(function () {
    var listFiltered = me.events.listFiltered();

    ko.utils.arrayForEach(me.events.list(), function (item) {
            index = listFiltered.indexOf(item);
        if (FILTERING_CASE_HERE) {
            if (index < 0) {
                listFiltered.push(item);
            }
        } else if (index >= 0) { // Delete
            listFiltered.splice(index, 1);
        }
    });
    return ko.utils.arrayFilter(me.events.list(), function (item) {
        return !(item.end().isBefore(filterStart) || item.start().isAfter(filterEnd));
    });
    return __rd++;
}).extend({ rateLimit: 0 });
this.events.listFiltered.subscribe(function () {
    debug('inside subscribe');
    debugger;
}, null, 'arrayChange');

但是我想知道这个问题是否更容易解决?

1 个答案:

答案 0 :(得分:2)

Knockout支持arrayChange任何observable,你必须专门启用它。

var computedTest = ko.computed(function() {  
    ...
}).extend({trackArrayChanges: true});

http://jsfiddle.net/mbest/A6D8u/2/

如果您查看Knockout源代码,this is what's done会自动查看可观察数组。

如果这是项目中的常见场景,您可以创建一个执行此操作的包装函数:

function computedArray() {
    return ko.computed.apply(ko, arguments).extend({trackArrayChanges: true});
}