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

后端 未结 3 1518
我在风中等你
我在风中等你 2021-02-12 16:59

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 g

相关标签:
3条回答
  • 2021-02-12 17:05

    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);
    
    0 讨论(0)
  • 2021-02-12 17:15

    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
    0 讨论(0)
  • 2021-02-12 17:18

    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());
    });
    
    0 讨论(0)
提交回复
热议问题