Câu hỏi Nhận giá trị trước đó của một quan sát trong đăng ký của cùng một quan sát


Có thể loại trực tiếp để có được giá trị hiện tại của một quan sát trong một thuê bao có thể quan sát được, trước khi nó nhận được giá trị mới không?

Thí dụ:

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

75
2017-10-10 15:25


gốc




Các câu trả lời:


Có một cách để đăng ký giá trị trước như sau:

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

81
2017-10-10 16:24





ko.subscribable.fn.subscribeChanged = function (callback) {
    var oldValue;
    this.subscribe(function (_oldValue) {
        oldValue = _oldValue;
    }, this, 'beforeChange');

    this.subscribe(function (newValue) {
        callback(newValue, oldValue);
    });
};

Sử dụng ở trên như thế này:

MyViewModel.MyObservableProperty.subscribeChanged(function (newValue, oldValue) {

});

139
2017-08-12 09:49



điều này thật tuyệt, bạn có yêu cầu kéo không? - Eric Hartford
khá mới để loại trực tiếp, nhưng tôi muốn đây là cách đăng ký mặc định được thiết lập. Hoặc .. fn này sẽ ít nhất là đầu ngứa đầu tiên của tôi khi tôi sử dụng 'đăng ký' cho lần đầu tiên. - bkwdesign
Đã có một số chuyển động về điều này trên github.com/knockout/knockout/issues/914. Có vẻ như nó được dự kiến ​​cho bản phát hành 3.4. - Aligned
Trong trường hợp loại giá trị quan sát được đăng ký là một mảng, bạn phải cắt nó, nếu không giá trị cũ sẽ luôn giống như giá trị mới. Kiểm tra một ví dụ làm việc, ở đây: jsfiddle.net/david_freire/xmk6u9yn/4 - David Freire
Mát mẻ. Đã thêm giá trị trả về là đối tượng đăng ký với dispose() chức năng gist.github.com/30ff1f5c1adf215179b0046515f86e45 - Michael


Ít thay đổi để trả lời Beagle90. Luôn tự trả lại đăng ký để có thể truy cập vứt bỏ () chẳng hạn.

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

20
2017-12-22 09:35





Các yêu cầu kéo để thêm tính năng này có một số mã khác nhau mà sẽ trở nên tốt hơn là dựa vào việc sử dụng beforeChange biến cố.

Tất cả tín dụng cho giải pháp cho 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);
    });
};

Để trích dẫn Michael:

Ban đầu tôi đã đề xuất sử dụng beforeChange để giải quyết vấn đề này nhưng từ đó đã nhận ra rằng nó không phải lúc nào cũng đáng tin cậy (ví dụ, nếu bạn gọi valueHasMutated() trên quan sát được).


13
2018-03-05 23:55





Tôi đã tìm thấy rằng tôi có thể gọi peek () từ một khả năng ghi có thể ghi được để có được giá trị trước đó.

Một cái gì đó như thế này (xem 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);
    }
});

3
2018-04-08 15:36



Điều đó không hoạt động, thật không may, kể từ thời điểm gọi lại đăng ký được gọi, giá trị đã thay đổi và do đó peek() sẽ cung cấp cho bạn giá trị mới. - Michael Teper
@MichaelTeper Tôi biết tôi đã đăng câu trả lời của mình một năm trước, nhưng sau khi tôi nhận được một số nhược điểm, tôi vừa thử nghiệm nó và nó hoạt động. Xem: jsfiddle.net/4MUWp - rjmunro
Ok tôi thấy những gì bạn đã làm ở đó ... Câu hỏi là về việc lấy giá trị trong một subscribe gọi lại mà không thể được thực hiện với peek (). Ví dụ của bạn chứng minh không có gì và có thể gây nhầm lẫn cho một người mới đến. Về cơ bản, bạn đang gói một biến riêng ở đây và hiển thị giá trị của nó trước khi đặt nó - vì vậy tất nhiên nó sẽ không thay đổi. - Simon_Weaver