2012-12-04 29 views
6

在我的模型中,我有一個異步加載的屬性。我希望它在加載後生成另一個模型屬性。如何創建可觸發的可觀察訂閱,只觸發一次?

我在想訂閱,可以在第一個屬性更改後起火,產生第二個屬性,然後設置得到 - 我不知道我怎樣才能從內部自行處理訂閱。

有沒有辦法在可觀察屬性更改後觸發一次事件?

回答

0

你可以寫一個擴展來抑制所有,但第一次發射:

ko.extenders.fireOnce= function(target) { 
    var fired=false; 
    var result = ko.computed({ 
     read: target, 
     write: function(newValue) { 
      var current = target(); 
      if (newValue!== current && !fired) { 
       fired=true; 
       target(newValue); 
      } 
     } 
    }); 
    result(target()); 
    return result; 
}; 

然後按如下方式使用它:

var myObservable = ko.Observable(blah).extend({fireOnce:null}); 
+0

這個擴展應該被命名爲建議'changeOnce',因爲除了首先價值變化將被忽略。 – blazkovicz

+0

@blazkovicz ...這是一個爲downvote你的依據是什麼? – spender

+2

是的,因爲問題是關於認購,thast閃光一次,你建議可觀察到的是_changes once_。這是兩個巨大的不同的事情。 – blazkovicz

21

從內部自行處理訂閱剛剛創建參考吧:

var subscription = yourObservable.subscribe(function (newValue) { 
    ... 
    subsription.dispose(); 
}); 

如果你不想每次都寫這段代碼,你可以擴展observab樂新方法:

ko.subscribable.fn.subscribeOnce = function (handler, owner, eventName) { 
    var subscription = this.subscribe(function (newValue) { 
     subscription.dispose(); 
     handler(newValue); 
    }, owner, eventName); 
    return subscription; 
}; 

... 

// usage 
var subscription = yourObservable.subsribeOnce(yourHandler); 

並且不要忘處置訂閱有關組件處置情況下,它沒有被解僱。

0

我們結束了這樣一個解決方案...

const subscription = observable.subscribe(() => { 
    subscription.dispose(); 
    doStuff(settings); 
}); 

希望有人可以使用它。

0

詳細闡述@blazkovicz答案,subscribeOnce可能會返回一個最終用新值解決的Promise。打開就如何暴露subscription對象;-)

ko.subscribable.fn.subscribeOnce = function (handler, owner, eventName) { 
    var subscribable = this; 
    var subscription; 
    return new Promise(function(resolve) { 
     subscription = subscribable.subscribe(resolve, owner, eventName); 
    }).then(function(newValue) { 
     subscription.dispose(); 
     handler && handler(newValue); 
     return newValue; 
    }); 
}; 

// usage 
yourObservable.subscribeOnce().then(function(newValue) { 
    ... 
});