2012-12-04 4 views
6

私のモデルでは、非同期にロードされるプロパティがあります。私はそれがロードされた後に別のモデルプロパティを生成したい。ノックアウト観察可能なサブスクリプションを作成するには、一度だけ起動する方法はありますか?

第1のプロパティの変更後に起動し、第2のプロパティを生成して廃棄されるサブスクリプションについて考えていました。どうやってサブスクリプションを内部から取り除くことができるのか分かりません。

観測可能なプロパティ変更後に1回のイベントを発生させる方法はありますか?

答えて

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 ...それはダウンボートのためのあなたの基礎ですか? – spender

+2

はい、質問はサブスクリプションに関するものだったので、一度は発砲し、_changes once_という観測可能性を示唆しました。これらは2つの大きな違いがあります。 – 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) { 
    ... 
}); 
関連する問題