86 votes

Obtenir la valeur précédente d'un observable en souscrivant au même observable.

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

Ejemplo:

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

152voto

Beagle90 Points 837
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) {

});

2 votes

Je suis assez nouveau dans Knockout, mais j'espère que c'est la façon dont l'abonnement par défaut a été configuré. Ou ce fn va au moins me gratter la première démangeaison quand j'utilise 'subscribe' pour la première fois.

1 votes

Il y a eu un certain mouvement à ce sujet sur github.com/knockout/knockout/issues/914 . On dirait que c'est prévu pour la version 3.4.

2 votes

Si le type de valeur de l'observable souscrit est un tableau, vous devez le découper, sinon l'ancienne valeur sera toujours la même que la nouvelle valeur. Voir un exemple concret, ici : jsfiddle.net/david_freire/xmk6u9yn/4

88voto

RP Niemeyer Points 81663

Il existe un moyen de souscrire à la valeur précédente de la manière suivante :

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

0 votes

Que fait this représente ici ?

21voto

Andries Points 698

Peu de changement par rapport à la réponse de Beagle90. Il faut toujours retourner l'abonnement lui-même pour pouvoir accéder à la fonction 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;
};

18voto

James Johnson Points 266

El demande de retrait pour ajouter cette fonctionnalité comporte un code différent qui s'avère meilleur que l'utilisation de la fonction beforeChange événement.

Tout le mérite de la solution revient à 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 :

J'avais initialement suggéré d'utiliser beforeChange pour résoudre ce problème mais nous avons depuis réalisé qu'il n'est pas toujours fiable (par exemple, si vous appelez valueHasMutated() sur l'observable).

3voto

rjmunro Points 10522

J'ai découvert que je peux appeler peek() à partir d'un observable calculé en écriture pour obtenir la valeur précédente.

Quelque chose comme ceci (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);
    }
});

1 votes

Malheureusement, cela ne fonctionne pas, car au moment où la fonction de rappel de souscription est appelée, la valeur a déjà été modifiée, et donc peek() vous donnera la nouvelle valeur.

0 votes

@MichaelTeper Je sais que j'ai posté ma réponse il y a un an, mais après avoir reçu quelques downvotes, je viens de la tester, et elle fonctionne. Voir : jsfiddle.net/4MUWp

0 votes

Ok, je vois ce que vous avez fait... La question portait sur la récupération de la valeur dans un fichier subscribe ce qui ne peut être fait avec peek(). Votre exemple ne prouve rien et pourrait dérouter un nouveau venu. En fait, vous encapsulez ici une variable privée et affichez sa valeur avant de la définir - elle n'aura donc bien sûr pas changé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X