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
});
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");
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) {
});
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;
};
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 appelezvalueHasMutated()
sur l'observable).
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);
}
});