86

在淘汰赛中是否有可能在订阅该 observable 之前获取 observable 的当前值,然后再接收新值?

例子:

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

5 回答 5

153
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) {

});
于 2013-08-12T09:49:54.960 回答
88

有一种方法可以像这样订阅之前的值:

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");
于 2012-10-10T16:24:27.087 回答
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;
};
于 2014-12-22T09:35:01.417 回答
18

添加此功能的拉取请求有一些不同的代码,这些代码最终比依赖使用beforeChange事件更好。

迈克尔·贝斯特( 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);
    });
};

引用迈克尔的话:

我最初建议使用beforeChange来解决这个问题,但后来意识到它并不总是可靠的(例如,如果你调用valueHasMutated()observable)。

于 2015-03-05T23:55:30.790 回答
3

我发现我可以从可写的计算 observable 中调用 peek() 来获取之前的值。

像这样的东西(见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);
    }
});
于 2013-04-08T15:36:54.303 回答