web-dev-qa-db-fra.com

Obtenez la valeur précédente d'un observable en vous abonnant au même observable

Est-il possible en knockout d'obtenir la valeur actuelle d'un observable dans un abonnement à cet observable, avant qu'il ne reçoive la nouvelle valeur?

Exemple:

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
});
83
KodeKreachor

Il existe un moyen de souscrire à la valeur précédente comme ceci:

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");
87
RP Niemeyer
ko.subscribable.fn.subscribeChanged = function (callback) {
    var oldValue;
    this.subscribe(function (_oldValue) {
        oldValue = _oldValue;
    }, this, 'beforeChange');

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

Utilisez ce qui précède comme ceci:

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

});
147
JBeagle

Peu de changement à la réponse Beagle90. Renvoyez toujours l'abonnement lui-même pour pouvoir accéder à dispose () par exemple.

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;
};
20
Andries

Le pull request pour ajouter cette fonctionnalité a un code différent qui s'avère mieux que de s'appuyer sur l'utilisation de l'événement beforeChange.

Tout le crédit pour la solution à 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);
    });
};

Pour citer Michael:

À l'origine, j'ai suggéré d'utiliser beforeChange pour résoudre ce problème, mais j'ai réalisé depuis que ce n'est pas toujours fiable (par exemple, si vous appelez valueHasMutated() sur l'observable).

16
James Johnson

J'ai trouvé que je peux appeler peek () à partir d'un observable calculé accessible en écriture pour obtenir la valeur avant.

Quelque chose comme ça (voir 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);
    }
});
3
rjmunro