La respuesta anterior es correcta, pero a menudo paso funciones a enlaces personalizados (una función que verifica los permisos o determina qué hacer en función de otra cosa, etc.). Lo que realmente necesitaba era desenvolver cualquier función, incluso si no es observable.
Lo siguiente desenvuelve de forma recursiva TODO:
ko.utils.unwrapFunction = function (func) {
if (typeof func != 'function') {
return func;
}
else {
return ko.utils.unwrapFunction(func());
}
};
Aquí hay un ejemplo de un enlace personalizado simple que escribí:
//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
}
}
}
De esta forma, bindingValue siempre contiene un valor. No necesito preocuparme por si pasé una función, un observable, un valor o incluso una función dentro de un observable. Esto desenvolverá correctamente todo hasta que llegue al objeto que quiero.
Espero que ayude a alguien.
ko.toJS(yourObject)
lugar de usarko.utils.unwrapObservable
, si está tratando de obtener una versión sin empaquetar del objeto para pasar a un widget o biblioteca de terceros. En general, es más seguro utilizarloko.utils.unwrapObservable
para respaldar observables y no observables.