A resposta anterior está correta, mas frequentemente passo funções para associações personalizadas (uma função que verifica as permissões ou determina o que fazer com base em outra coisa, etc). O que eu realmente precisava era desembrulhar qualquer função, mesmo que não fosse observável.
O seguinte desembrulha recursivamente TUDO:
ko.utils.unwrapFunction = function (func) {
if (typeof func != 'function') {
return func;
}
else {
return ko.utils.unwrapFunction(func());
}
};
Aqui está um exemplo de uma ligação personalizada simples que escrevi:
//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
}
}
}
Dessa forma, bindingValue sempre contém um valor. Não preciso me preocupar se passei uma função, um observável, um valor ou mesmo uma função dentro de um observável. Isso vai desembrulhar tudo corretamente até chegar ao objeto que desejo.
Espero que ajude alguém.
ko.toJS(yourObject)
do que usarko.utils.unwrapObservable
, se estiver tentando fazer com que uma versão desembrulhada do objeto passe para um widget ou biblioteca de terceiros. Em geral, é mais seguro usarko.utils.unwrapObservable
para apoiar observáveis e não observáveis.