在订阅相同的observable时获取observable的先前值

时间:2012-10-10 15:25:54

标签: knockout.js knockout-2.0 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
});

5 个答案:

答案 0 :(得分:145)

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

});

答案 1 :(得分:85)

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

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

答案 2 :(得分:20)

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

答案 3 :(得分:16)

添加此功能的pull request有一些不同的代码,比使用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来解决这个问题,但后来意识到它并不总是可靠的(例如,如果你在observable上调用valueHasMutated())。

答案 4 :(得分:3)

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

这样的事情(见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);
    }
});