Когда использовать ko.utils.unwrapObservable?

Я написал несколько пользовательских привязок, используя KnockoutJS. Я до сих пор не уверен, когда использовать ko.utils.unwrapObservable(item) Глядя на код, этот вызов в основном проверяет, является ли item наблюдаемым. Если это так, вернуть значение(), если нет, просто вернуть значение. Глядя на раздел Knockout о создании пользовательских привязок, они имеют следующий синтаксис:

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

В этом случае они вызывают наблюдаемую ko.utils.unwrapObservable via () но затем также вызывают ko.utils.unwrapObservable. Я просто пытаюсь понять, когда использовать один против другого, или я должен просто всегда следовать вышеупомянутому образцу и использовать оба.

Ответ 1

Вы должны использовать ko.utils.unwrapObservable в тех случаях, когда вы не знаете, было ли вам предоставлено наблюдение или нет. Обычно это было бы в пользовательском связывании, где наблюдаемое или не наблюдаемое может быть связано с ним.

В коде, который у вас выше, вызов valueAccessor() фактически не разворачивает наблюдаемый. Он просто извлекает значение, которое было передано связыванию в правильном контексте (оно обернуто в функцию для его защиты). Возвращаемое значение valueAccessor() может быть наблюдаемым или нет. Это то, что было передано связыванию.

Ответ 2

Более ранний ответ верен, но часто я передаю функции пользовательским связям (функция, которая проверяет разрешения или определяет, что делать на основе чего-то еще и т.д.). Мне действительно нужно было развернуть любую функцию, даже если она не наблюдаема.

Следующие рекурсивно разворачивают ВСЕ:

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

Таким образом, bindingValue всегда содержит значение. Мне не нужно беспокоиться о том, прошел ли я в функции, наблюдаемом, значении или даже функции внутри наблюдаемого. Это будет правильно разворачивать все, пока оно не попадет на объект, который я хочу.

Надеюсь, что это поможет кому-то.