Ko.utils.unwrapObservable ne zaman kullanılır?


114

KnockoutJS kullanarak birkaç özel bağlama yazdım. Koda bakmayı ne zaman kullanacağımdan hala emin değilim ko.utils.unwrapObservable(item), bu çağrı temelde itemgözlemlenebilir olup olmadığını kontrol ediyor . Eğer öyleyse, değeri () döndür, değilse, sadece değeri döndür. Altını Gizleme ile ilgili özel bağlamalar oluşturma bölümüne bakıldığında, bunlar aşağıdaki sözdizimine sahiptir:

var value = valueAccessor(), allBindings = allBindingsAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);

Bu durumda, gözlemlenebilir olanı çağırırlar ()ama sonra da çağırırlar ko.utils.unwrapObservable. Sadece birini diğerine karşı ne zaman kullanacağımı veya her zaman yukarıdaki modeli takip edip ikisini de kullanmam gerektiğini anlamaya çalışıyorum.

Yanıtlar:


142

Size ko.utils.unwrapObservablegözlemlenebilir olup olmadığını bilmediğiniz durumlarda kullanmalısınız . Bu genellikle, gözlemlenebilir veya gözlemlenemeyen birinin kendisine bağlı olabileceği özel bir bağlamada olacaktır.

Yukarıda sahip olduğunuz kodda, çağrının valueAccessor()aslında bir gözlemlenebilir olanı açması değil. Yalnızca doğru bağlamda bağlanmaya iletilen değeri alır (onu korumak için bir işleve sarılır). Dönüş değeri valueAccessor()gözlemlenebilir olabilir veya olmayabilir. Bağlayıcıya geçen şey budur.


4
Gerçekten duruma bağlı. Bazı özel bağlamalar yalnızca gözlemlenebilirlerle çalışmak üzere tasarlanmıştır, bu nedenle önden (ko.isObservable) bunun bir gözlemlenebilir olup olmadığını kontrol edebilir ve ardından () ile açmakta özgürsünüz. İç içe gözlemlenebilirler içeren bir nesne alıyorsanız, nesnenin sarılmamış bir sürümünü bir parçacığa veya üçüncü taraf kitaplığına geçirmeye çalışıyorsanız, ko.toJS(yourObject)kullanmak yerine a yapmak daha iyidir ko.utils.unwrapObservable. Genel olarak, ko.utils.unwrapObservablegözlenebilirleri ve gözlenemezleri desteklemek için kullanmak en güvenlisidir .
RP Niemeyer

2
Sanırım amacının ne olduğu konusunda kafam karıştı ko.utils.unwrapObservable. Koda bakıldığında, sadece gözlemlenebilir olup olmadığını kontrol eder ve eğer öyleyse, Knockout (), gözlemlenebilirin değerini almak için çağırır , aksi takdirde, sadece gözlemlenemeyen değeri döndürür. İlgilendiğim tek şey bağlayıcıya aktarılan verilerin değeriyse, neden her zaman kullanamıyorum ()?
arb

17
Bir bağlamada gözlemlenebilir mi yoksa gözlemlenemez mi geçirdiğinizi bilmiyorsunuz. Diyelim ki var myBindingve biri gibi bağlanıyor data-bind="myBinding: myValue". myValuebir gözlemlenebilir olabilir veya sadece görünüm modelinde basit bir özellik olabilir. Eğer bu sadece bir özellik ise ve onu bir işlev olarak adlandırırsam, o zaman bir hata alırsınız. ko.utils.unwrapObservableGözlenebilir bir şekilde geçirilip geçirilmediğinize bakılmaksızın size değeri güvenli bir şekilde döndürecektir.
RP Niemeyer

10
Ayrıca 'ko.unwrap' kısayolunu kullanmanızı öneririm çünkü 'ko.utils.unwrapObservable' çok uzun bir ifadedir.
Ivan Nikitin

3
@IvanNikitin - tabii, sadece ko.unwrap3.0+ sürümünde mevcut olduğunu belirtmek istedim . 3.0'dan daha eski kullanıyorsanız ko.utils.unwrapObservable, hala oradadır.
RP Niemeyer

12

Önceki cevap doğrudur, ancak çoğu zaman işlevleri özel bağlamalara geçiriyorum (izinleri kontrol eden veya başka bir şeye dayanarak ne yapılacağını belirleyen bir işlev, vb.). Gerçekten ihtiyacım olan şey, gözlemlenebilir olmasa bile herhangi bir işlevi açmaktı.

Aşağıdaki, HER ŞEYİ özyinelemeli olarak çözer:

ko.utils.unwrapFunction = function (func) {
    if (typeof func != 'function') {
        return func;
    }
    else {
        return ko.utils.unwrapFunction(func());
    }
};

İşte yazdığım basit bir özel bağlama örneği:

//replaces single and double 'smart' quotes users commonly paste in from word into textareas and textboxes with normal text equivalents
//USAGE:
//data-bind="replaceWordChars:true
//also works with valueUpdate:'keyup' if you want"

ko.bindingHandlers.replaceWordChars = {
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var bindingValue = ko.utils.unwrapFunction(valueAccessor);

        if (bindingValue) {
            $(element).val(removeMSWordChars(allBindingsAccessor().value())); //update DOM - not sure why I should need to do this, but just updating viewModel doesn't always update DOM correctly for me
            allBindingsAccessor().value($(element).val()); //update viewModel
        }
    }
}

Bu şekilde bindingValue her zaman bir değer içerir. Bir gözlemlenebilir içinde bir fonksiyon, bir gözlemlenebilir, bir değer veya hatta bir fonksiyon geçip geçmediğim konusunda endişelenmeme gerek yok. Bu, istediğim nesneye ulaşana kadar her şeyi düzgün bir şekilde açacaktır.

Umarım bu birine yardımcı olur.

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.