在observable上重载订阅

时间:2014-04-30 21:01:21

标签: knockout.js subscription observable

是否可以在观察者身上超载预先存在的订阅?如果是这样的话?

this.myObservable = ko.observable();
this.myObservable.subscribe(function(value){
    /* stuff worth subscribing for */
});
/* stuff going on */
/* ... */
/* more stuff going on */

// now at this point I want to check if something has subscribed to
// this.myObservable and if so I want the subscription to do a bit extra

我知道我可以将"额外的"首先在初始订阅中,但我想知道是否可以检查订阅然后重载它。

2 个答案:

答案 0 :(得分:2)

我确信有一种神奇的JavaScript方法可以做到这一点,但是在阅读本文时出于某种原因而想到的一种方式(不是那种幻想,请注意)就像这样 -

function doSomething() { alert('Hey'); }
function doSomethingElse() { alert('Hey2'); }

ko.extenders.functionAdder = function (target, firstFunc) {
    target.functionBag = target.functionBag ? target.functionBag : [];
    target.functionBag.push(firstFunc);
    target.subscribe(function(value){
        ko.utils.arrayForEach(target.functionBag, function (item) {
            item();
        }); 
    });
}    
self.things = ko.observableArray([new Message('Hey')]).extend({ functionAdder: doSomething });

// Later on

target.functionBag.push(doSomethingElse);

示例 -

http://jsfiddle.net/k94qT/

可能有一种更合适的方法可以重新打开函数并向其添加内容,但这听起来像是Ember.js的reopenClass,我不知道Knockout.js中有类似的东西

答案 1 :(得分:1)

Knockout没有提供任何扩展订阅的方法。但是你可以包装subscribe方法来提供一种方法。这是一个例子:

ko.subscribable.fn.subscribe = (function (originalFunction) {
    return function (callback, callbackTarget, event) {
        var boundCallback = callbackTarget ? callback.bind(callbackTarget) : callback,
            currentCallback = boundCallback,
            passthroughCallback = function (value) { currentCallback(value) },
            subscription = originalFunction.call(this, passthroughCallback, null, event);

        subscription.extend = function (newCallback) {
            currentCallback = newCallback.bind(null, currentCallback);
        };
        return subscription;
    }
})(ko.subscribable.fn.subscribe);

http://jsfiddle.net/mbest/LKrr9/

您还提到稍后可以从observable中检索订阅。您可以通过在上面的函数中添加一行来实现这一点:

this.latestSubscription = subscription;

这假定不会处理订阅。如果你想获得最新的非处置订阅,它会有点复杂。

注意:上述扩展subscribe的方法仅适用于Knockout> = 3.1.0。对于以前的版本,您必须在扩展程序中附加新的subscribe方法。