订阅相同的可观察对象,获取该可观察对象的先前值


85

剔除是否有可能在获取新观察值之前获取该观察值的预订中的当前值?

例:

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

Answers:


88

有一种方法可以像这样对before值进行订阅:

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

this在这里代表什么?
Thanasis Ioannidis

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

});

2
淘汰赛还不是很新,但是我希望这是默认订阅的设置方式。或者..当我第一次使用“订阅”时,此fn至少会刮擦我的第一个痒。
bkwdesign

1
github.com/knockout/knockout/issues/914上对此进行了一些移动。看起来它计划在3.4版本中发布。
不结盟

2
如果订阅的可观察值类型是数组,则必须对其进行切片,否则oldValue将始终与newValue相同。在这里检查一个工作示例:jsfiddle.net/david_freire/xmk6u9yn/4
David Freire

1
凉。添加了一个返回值,该返回值是带有dispose()功能gist.github.com/30ff1f5c1adf215179b0046515f86e45
Michael

哦,刚看到git对话。
迈克尔

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

1
这是真正的提升,但是.dispose从中调用返回值将只处理第二个订阅,而不是'beforeChange'订阅
TRManderson

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()可观察对象)。


3

我发现我可以从可写的可计算观察对象中调用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);
    }
});

1
不幸的是,这是行不通的,因为在调用订阅回调时,该值已经更改,因此peek()将为您提供新值。
2014年

@MichaelTeper我知道我在一年前发布了我的答案,但是当我得到一些赞成票之后,我就对其进行了测试,并且它确实起作用。请参阅:jsfiddle.net/4MUWp
rjmunro 2014年

好的,我知道您在这里做了什么。问题是关于在subscribe回调中检索值,而使用peek()无法完成该回调。您的示例无法证明任何事实,并且可能会使新来者感到困惑。您基本上是在这里包装一个私有变量,并在设置它之前显示它的值-因此,它当然不会改变。
Simon_Weaver 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.