La réponse précédente est correcte, mais souvent je transmets des fonctions à des liaisons personnalisées (une fonction qui vérifie les autorisations, ou détermine quoi faire en fonction de quelque chose d'autre, etc). Ce dont j'avais vraiment besoin était de déballer toute fonction, même si ce n'est pas un observable.
Le code suivant déballe RÉCURREMMENT TOUT :
ko.utils.unwrapFunction = function (func) {
if (typeof func != 'function') {
return func;
}
else {
return ko.utils.unwrapFunction(func());
}
};
Voici un exemple d'une simple liaison personnalisée que j'ai écrite :
// remplace les guillemets simples et doubles 'intelligents' que les utilisateurs collent souvent depuis Word dans les zones de texte et les zones de texte par des équivalents de texte normal
// USAGE :
// data-bind="replaceWordChars:true
// fonctionne également avec valueUpdate:'keyup' si vous le souhaitez"
ko.bindingHandlers.replaceWordChars = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var bindingValue = ko.utils.unwrapFunction(valueAccessor);
if (bindingValue) {
$(element).val(removeMSWordChars(allBindingsAccessor().value())); // mettre à jour le DOM - je ne suis pas sûr pourquoi j'aurais besoin de le faire, mais mettre à jour simplement le viewModel ne met pas toujours correctement à jour le DOM pour moi
allBindingsAccessor().value($(element).val()); // mettre à jour le viewModel
}
}
}
De cette manière, bindingValue contient toujours une valeur. Je n'ai pas besoin de m'inquiéter si j'ai transmis une fonction, un observable, une valeur, ou même une fonction à l'intérieur d'un observable. Cela déballera correctement tout jusqu'à ce qu'il atteigne l'objet voulu.
J'espère que cela aidera quelqu'un.