Aynı gözlemlenebilir abone olarak bir gözlemlenebilirin önceki değerini alın


86

Nakavtta, yeni değeri almadan önce, bir gözlemlenebilir aboneliğin içindeki bir gözlemlenebilirin mevcut değerini elde etmek mümkün müdür?

Misal:

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

Yanıtlar:


88

Önceki değere abone olmanın bir yolu var:

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

thisburada ne anlama geliyor?
— Thanasis Ioannidis

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

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

Yukarıdakileri şu şekilde kullanın:

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

});

2
Nakavt için oldukça yeni, ancak bunun varsayılan abonelik kurulumunun bu şekilde olmasını diliyorum. Ya da .. bu fn en azından "abone ol" u ilk kez kullandığımda ilk kaşıntımı kesecek.
— bkwdesign

1
Bu konuda github.com/knockout/knockout/issues/914 adresinde bazı hareketler oldu . 3.4 sürümü için planlanmış gibi görünüyor.
— AlignedDev

2
Abone olunan gözlemlenebilir değer türünün bir Dizi olması durumunda, onu dilimlemeniz gerekir, aksi takdirde oldValue her zaman newValue ile aynı olacaktır. Burada çalışan bir örneği kontrol edin: jsfiddle.net/david_freire/xmk6u9yn/4
— David Freire


Oh az önce git konuşmasını gördüm.
— Michael

21

Beagle90 cevabında küçük bir değişiklik. Örneğin, dispose () öğesine erişebilmek için aboneliğin kendisini daima iade edin.

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

2
Bu gerçek bir adım yukarı, ancak arama .disposesadece atmayın ikinci abonelik bundan dönüş değeri üzerinde olacak değil 'beforeChange'abonelik
— TRManderson

18

Çekme isteği bu özelliği eklemek daha iyi kullanarak güvenmek yerine olmak winds bazı farklı kodu vardır beforeChangeolay.

Michael Best'e çözüm için tüm övgü

ko.subscribable.fn.subscribeChanged = function (callback) {
    var savedValue = this.peek();
    return this.subscribe(function (latestValue) {
        var oldValue = savedValue;
        savedValue = latestValue;
        callback(latestValue, oldValue);
    });
};

Michael'dan alıntı yapmak için:

Başlangıçta beforeChangebu sorunu çözmek için kullanmayı önerdim, ancak o zamandan beri her zaman güvenilir olmadığını fark ettim (örneğin, valueHasMutated()gözlemlenebilir olanı ararsanız ).


3

Önceki değeri elde etmek için yazılabilir bir hesaplanmış gözlemlenebilirden peek () çağırabileceğimi buldum.

Bunun gibi bir şey (bkz. 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
Bu maalesef işe yaramıyor, çünkü abonelik geri araması çağrıldığında, değer zaten değişti ve bu nedenle peek()size yeni değeri verecektir.
— Michael Teper

@MichaelTeper Cevabımı bir yıl önce gönderdiğimi biliyorum, ancak bazı olumsuz oylar aldıktan sonra test ettim ve işe yarıyor. Bakınız: jsfiddle.net/4MUWp
— rjmunro

Tamam, orada ne yaptığınızı görüyorum ... Soru, subscribepeek () ile yapılamayan bir geri aramadaki değeri geri almakla ilgiliydi . Örneğiniz hiçbir şeyi kanıtlamaz ve yeni gelen birinin kafasını karıştırabilir. Temel olarak burada özel bir değişkeni sarmalıyorsunuz ve değerini ayarlamadan önce gösteriyorsunuz - bu yüzden elbette değişmeyecek.
— Simon_Weaver
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.