2012-10-10 70 views

回答

77

有一个办法这样值之前做了订阅的:

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

我发现,我可以打电话从计算观察到一个可写的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); 
    } 
}); 
+1

不幸的是,由于在调用订阅回调的时候,值已经改变了,所以'peek()'会给你新的值。 –

+0

@MichaelTeper我知道我在一年前发布了我的答案,但是在我收到了一些提示后,我刚刚测试了它,它确实有效。请参阅:http://jsfiddle.net/4MUWp/ – rjmunro

+0

好吧,我看到你在那里做了什么...问题是关于检索'订阅'回调中的值,这是peek()无法完成的。你的榜样证明什么都没有,并可能混淆一个新来者。你基本上是在这里封装一个私有变量,并在设置它之前显示它的值 - 所以它当然不会改变。 –

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

}); 
+12

这很酷,你有没有提出要求? –

+2

相当新的淘汰赛,但我希望这是默认订阅的方式设置。或者..当我第一次使用'订阅'时,这个fn至少会抓我的第一个痒。 – bkwdesign

+0

https://github.com/knockout/knockout/issues/914上有一些动作。看起来它是为3.4版本发布的。 – Aligned

15

变化不大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; 
}; 
12

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来解决这个问题,但都因为意识到它并不总是可靠的(例如最初的建议,如果你在可观察的情况下调用valueHasMutated())。