Knockout-2.2.0, subscribe get value before change AND new value

不羁岁月 提交于 2019-12-04 17:03:48

问题


jsfiddle link: http://jsfiddle.net/T8ee7/

When I call Knockout's subscribe method is there a way I can get both the previous and new value? Right now, I can only call get these values separately. I want to trigger some code if the old and new value are different.

I suppose I could do the following, but it can get messy... (http://jsfiddle.net/MV3fN/)

var sv = sv || {};
sv.PagedRequest = function (pageNumber, pageSize) {
    this.pageNumber = ko.observable(pageNumber || 1);
    this.numberOfPages = ko.observable(1);
    this.pageSize = ko.observable(pageSize || sv.DefaultPageSize);
};


var _pagedRequest = new sv.PagedRequest();
var oldValue;
_pagedRequest.pageNumber.subscribe(function (previousValue) {
    console.log("old: " + previousValue);
    oldValue = previousValue;
}, _pagedRequest, "beforeChange");


_pagedRequest.pageNumber.subscribe(function (newValue) {

    console.log("new: " + newValue);
    if (oldValue != newValue) {
        console.log("value changed!");
    }

});

_pagedRequest.pageNumber(10);
_pagedRequest.pageNumber(20);
​

回答1:


I prefer using an observable extender.

http://jsfiddle.net/neonms92/xybGG/

Extender:

ko.extenders.withPrevious = function (target) {
    // Define new properties for previous value and whether it's changed
    target.previous = ko.observable();
    target.changed = ko.computed(function () { return target() !== target.previous(); });

    // Subscribe to observable to update previous, before change.
    target.subscribe(function (v) {
        target.previous(v);
    }, null, 'beforeChange');

    // Return modified observable
    return target;
}

Example Usage:

// Define observable using 'withPrevious' extension
self.hours = ko.observable().extend({ withPrevious: 1 });

// Subscribe to observable like normal
self.hours.subscribe(function () {
    if (!self.hours.changed()) return; // Cancel if value hasn't changed
    print('Hours changed from ' + self.hours.previous() + ' to ' + self.hours());
});



回答2:


This seems to work for me

ko.observable.fn.beforeAndAfterSubscribe = function (callback, target) {
 var _oldValue;
 this.subscribe(function (oldValue) {
     _oldValue = oldValue;
 }, null, 'beforeChange');
   this.subscribe(function (newValue) {
     callback.call(target, _oldValue, newValue);
 });
}; 
  • See more at: http://ideone.com/NPpNcB#sthash.wJn57567.dpuf



回答3:


http://jsfiddle.net/MV3fN/3/

var sv = sv || {};
sv.PagedRequest = function (pageNumber, pageSize) {
    var self = this;
    self.pageNumber = ko.observable(pageNumber || 1);
    self.numberOfPages = ko.observable(1);
    self.pageSize = ko.observable(pageSize || sv.DefaultPageSize);

    self.pageNumber.subscribe(function (previousValue) {
        console.log(previousValue);
        console.log(self.pageNumber.arguments[0]);
        if (previousValue != _pagedRequest.pageNumber.arguments[0]) {
            console.log('value changed');
        } 
        else {
            //This won't get executed because KO doesn't
            //call the function if the value doesn't change
            console.log('not changed');
        }
    }, _pagedRequest, "beforeChange");
};

var _pagedRequest = new sv.PagedRequest();

_pagedRequest.pageNumber(10);
_pagedRequest.pageNumber(20);
_pagedRequest.pageNumber(20);
_pagedRequest.pageNumber(5);

I don't know if you're really supposed to use arguments[0], but it seems to work.

You could also set up your own method to accomplish this in a much cleaner way:

http://jsfiddle.net/PXKgr/2/

...
    self.setPageNumber = function(page) {
        console.log(self.pageNumber());
        console.log(page);
        if (self.pageNumber() != page) {
            console.log('value changed');
        }
        else {
            console.log('not changed');
        }
        self.pageNumber(page);
    };
...
_pagedRequest.setPageNumber(10);
_pagedRequest.setPageNumber(20);
_pagedRequest.setPageNumber(20);
_pagedRequest.setPageNumber(5);


来源:https://stackoverflow.com/questions/14076865/knockout-2-2-0-subscribe-get-value-before-change-and-new-value

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!