同じオブザーバブルのサブスクライブでオブザーバブルの以前の値を取得します


85

ノックアウトで、新しい値を受け取る前に、そのオブザーバブルへのサブスクリプション内のオブザーバブルの現在の値を取得することは可能ですか?

例:

this.myObservable = ko.observable();
this.myObservable.subscribe(function(newValue){
    //I'd like to get the previous value of 'myObservable' here before it's set to newValue
});

回答:


88

次のようにbefore値へのサブスクリプションを行う方法があります。

this.myObservable = ko.observable();
this.myObservable.subscribe(function(previousValue){
    //I'd like to get the previous value of 'myObservable' here before it's set to newValue
}, this, "beforeChange");

thisここでは何の略ですか?
Thanasis Ioannidis

151
ko.subscribable.fn.subscribeChanged = function (callback) {
    var oldValue;
    this.subscribe(function (_oldValue) {
        oldValue = _oldValue;
    }, this, 'beforeChange');

    this.subscribe(function (newValue) {
        callback(newValue, oldValue);
    });
};

上記のように使用します。

MyViewModel.MyObservableProperty.subscribeChanged(function (newValue, oldValue) {

});

2
ノックアウトはかなり新しいですが、これがデフォルトのサブスクライブの設定方法であることを願っています。または..このfnは、「subscribe」を初めて使用するときに、少なくとも私の最初のかゆみを掻きます。
bkwdesign 2013年

1
github.com/knockout/knockout/issues/914でこれに関する動きがありました。3.4リリースが予定されているようです。
2015

2
サブスクライブされた監視可能な値の型が配列の場合は、スライスする必要があります。そうでない場合、oldValueは常にnewValueと同じになります。ここで実際の例を確認してください:jsfiddle.net/david_freire/xmk6u9yn/4
David Freire


ああ、gitの会話を見たところです。
Michael

21

Beagle90の答えに少し変更。たとえば、dispose()にアクセスできるようにするには、常にサブスクリプション自体を返します。

ko.subscribable.fn.subscribeChanged = function (callback) {
    var oldValue;
    this.subscribe(function (_oldValue) {
        oldValue = _oldValue;
    }, this, 'beforeChange');

    var subscription = this.subscribe(function (newValue) {
        callback(newValue, oldValue);
    });

    // always return subscription
    return subscription;
};

1
これが本当のステップアップですが、呼び出す.disposeだけで処分2番目のサブスクリプションのこのからの戻り値になり、いない'beforeChange'サブスクリプション
TRManderson

18

プルリクエストこの機能を追加するためには、より良い使用に頼るよりもされて巻き取るいくつかの異なるコードがあるbeforeChangeイベントを。

解決策のためのすべてのクレジットマイケル・ベスト

ko.subscribable.fn.subscribeChanged = function (callback) {
    var savedValue = this.peek();
    return this.subscribe(function (latestValue) {
        var oldValue = savedValue;
        savedValue = latestValue;
        callback(latestValue, oldValue);
    });
};

マイケルを引用するには:

私は当初、beforeChangeこの問題を解決するためにを使用することを提案しましたが、その後、常に信頼できるとは限らないことに気付きました(たとえば、valueHasMutated()observableを呼び出す場合)。


3

書き込み可能な計算されたobservableからpeek()を呼び出して、before値を取得できることがわかりました。

このようなもの(http://jsfiddle.net/4MUWpを参照):

var enclosedObservable = ko.observable();
this.myObservable = ko.computed({
    read: enclosedObservable,
    write: function (newValue) {
        var oldValue = enclosedObservable.peek();
        alert(oldValue);
        enclosedObservable(newValue);
    }
});

1
残念ながら、これは機能しません。サブスクライブコールバックが呼び出されるまでに、値はすでに変更されているためpeek()、新しい値が提供されます。
Michael Teper 2014年

@MichaelTeper 1年前に回答を投稿したことは知っていますが、いくつかの反対票を受け取った後、テストしたところ、機能します。参照:jsfiddle.net/4MUWp
rjmunro 2014

わかりました。そこで何をしたかわかります...質問はsubscribe、peek()では実行できないコールバックで値を取得することについてでした。あなたの例は何も証明せず、新参者を混乱させる可能性があります。基本的にここでプライベート変数をラップし、設定する前にその値を表示します-もちろん、変更されていません。
Simon_Weaver 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.