Коли використовувати ko.utils.unwrapObservable?


114

Я написав кілька спеціальних прив’язок за допомогою KnockoutJS. Я все ще не впевнений, коли використовувати ko.utils.unwrapObservable(item)Дивлячись на код, цей виклик в основному перевіряє, чи itemє спостережуваним. Якщо це так, поверніть значення (), якщо це не так, просто поверніть значення. Розглядаючи розділ на нокаут про створення спеціальних прив’язок, вони мають такий синтаксис:

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

У цьому випадку вони викликають спостережуване через, ()але потім також дзвонять ko.utils.unwrapObservable. Я просто намагаюся впоратися з тим, коли використовувати одне проти іншого або якщо мені просто завжди слід дотримуватися вищезазначеної схеми та використовувати обоє.

Відповіді:


142

Вам слід користуватися ko.utils.unwrapObservableу випадках, коли ви не знаєте, чи вам дали спостереження чи ні. Зазвичай це стосується звичайного прив'язки, коли спостережуване або неспостережне може бути пов'язане з ним.

У наведеному вище коді заклик valueAccessor()насправді не розгортає спостережуване. Це просто отримання значення, яке було передано до прив'язки у правильному контексті (воно перетворюється на функцію захисту). Повернене значення valueAccessor()може бути помітним чи ні. Це все, що було передано до обов'язкового.


4
Це дійсно залежить від ситуації. Деякі спеціальні прив’язки призначені для роботи лише з спостережними характеристиками, тому ви можете переконатися, що фронт (ko.isObservable) є спостережуваним, і тоді ви зможете розгортати його (). Якщо ви отримуєте об'єкт, який, можливо, вклав спостереження, то вам краще робити, ko.toJS(yourObject)а не використовувати ko.utils.unwrapObservable, якщо ви намагаєтесь отримати нерозгорнуту версію об’єкта для переходу у віджет або сторонній бібліотеку. Загалом, це найбезпечніше використовувати ko.utils.unwrapObservableдля підтримки спостережуваних та неспостережних.
RP Niemeyer

2
Напевно, я плутаю те, в чому ko.utils.unwrapObservableполягає мета . Дивлячись на код, він просто перевіряє, чи є він спостережуваним, і якщо він є, Knockout викликає, ()щоб отримати значення спостережуваного, інакше він просто повертає значення для невидимого. Якщо мене цікавить лише цінність даних, переданих у прив'язку, чому я не можу завжди використовувати їх ()?
арб

17
Ви не знаєте, чи будете ви проходили спостереження чи неспостереження у прив'язці. Скажіть, у мене є, myBindingа хтось пов'язує, тобто подобається data-bind="myBinding: myValue". myValueце може бути спостережуваним, а може бути просто властивістю моделі перегляду. Якщо це лише властивість, і я називаю це функцією, то ви отримаєте помилку. ko.utils.unwrapObservableнадійно поверне вам цінність незалежно від того, переходили ви до спостереження чи ні.
РП Німайєр

10
Я також рекомендую використовувати скорочення "ko.unwrap", оскільки "ko.utils.unwrapObservable" - це дуже довгі вирази.
Іван Нікітін

3
@IvanNikitin - впевнено, просто хотів зазначити, що ko.unwrapдоступно в версії 3.0+. Якщо ви використовуєте старше 3,0, то ko.utils.unwrapObservableвсе одно є.
RP Niemeyer

12

Раніша відповідь правильна, але часто я передаю функції під власні прив'язки (функція, яка перевіряє дозволи, або визначає, що робити на основі чогось іншого тощо). Мені справді потрібно було розгортати будь-яку функцію, навіть якщо вона не спостерігається.

Наступне рекурсивно розгортає ВСЕ:

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

Ось приклад простого користувацького в’язки, яке я написав:

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

Таким чином, прив'язкаValue завжди містить значення. Мені не потрібно хвилюватися, якщо я передав функцію, спостережуване, значення або навіть функцію всередині спостережуваного. Це належним чином розмотає все, поки воно не потрапить на об'єкт, який я хочу.

Сподіваюся, що хтось допомагає.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.