2012-10-10 13 views

Odpowiedz

77

Jest na to sposób to zrobić w ramach subskrypcji przed wartością takiego:

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"); 
3

Odkryłem, że mogę zadzwonić peek() z zapisywalnego obliczonego obserwowalne aby uzyskać poprzednią wartość.

Coś takiego (patrz 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

To nie działa, niestety, ponieważ przed wywołaniem wywołania zwrotnego, wartość już się zmieniła, więc 'peek()' da ci nową wartość. –

+0

@MichaelTeper Wiem, że wysłałem swoją odpowiedź rok temu, ale po tym, jak dostałem kilka negatywnych opinii, właśnie to przetestowałem i to działa. Zobacz: http://jsfiddle.net/4MUWp/ – rjmunro

+0

Ok Widzę, co tam zrobiłeś ... Pytanie dotyczyło odzyskania wartości w wywołaniu zwrotnym 'subscribe', którego nie można zrobić za pomocą peek(). Twój przykład niczego nie dowodzi i może zmylić nowicjusza. Zasadniczo zawijacie tutaj prywatną zmienną i wyświetlacie jej wartość przed jej ustawieniem - więc oczywiście to się nie zmieni. –

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

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

Użyj powyższego tak:

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

}); 
+12

To jest fajne, czy wykonałeś polecenie ściągnięcia? –

+2

całkiem nowy nokaut, ale żałuję, że nie było tak, jak skonfigurowano domyślną subskrypcję. Albo ... ten fn przynajmniej podrapie moją pierwszą sztuczkę, kiedy po raz pierwszy używam opcji "subskrybuj". – bkwdesign

+0

Nastąpił pewien ruch w tej sprawie na https://github.com/knockout/knockout/issues/914. Wygląda na to, że jest przeznaczony na wersję 3.4. – Aligned

15

Mała zmiana Beagle90 odpowiedź. Zawsze zwracaj samą subskrypcję, aby mieć na przykład dostęp do 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; 
}; 
12

pull request dodać tę funkcję ma jakiś inny kod, który nakręca jest lepszy niż opierając się na wykorzystaniu zdarzenia beforeChange.

Wszystko kredyt na rozwiązanie Michael Best

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

zacytować Michael:

pierwotnie zasugerował użycie beforeChange, aby rozwiązać ten problem, ale ponieważ zrozumiał, że to nie zawsze wiarygodne (na przykład, jeśli wywołasz valueHasMutated() na obserwowalnym).