web-dev-qa-db-fra.com

Quand utiliser ko.utils.unwrapObservable?

J'ai écrit quelques liaisons personnalisées à l'aide de KnockoutJS. Je ne suis toujours pas sûr d'utiliser ko.utils.unwrapObservable(item). En regardant le code, cet appel vérifie essentiellement si item est observable. Si c'est le cas, retourne la valeur (), sinon, retourne simplement la valeur. La section sur Knockout concernant la création de liaisons personnalisées présente la syntaxe suivante:

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

Dans ce cas, ils invoquent l'observable via () mais appelez aussi ko.utils.unwrapObservable. J'essaie simplement de savoir quand utiliser l'un par rapport à l'autre ou si je dois toujours suivre le schéma ci-dessus et utiliser les deux.

111
arb

Vous devez utiliser ko.utils.unwrapObservable Dans les cas où vous ne savez pas si un observable vous a été attribué ou non. Ce serait généralement dans une liaison personnalisée où un observable ou non-observable pourrait être lié contre elle.

Dans le code que vous avez ci-dessus, l'appel à valueAccessor() ne décompresse pas réellement un observable. Il s'agit simplement de récupérer la valeur transmise à la liaison dans le bon contexte (elle est encapsulée dans une fonction pour la protéger). La valeur de retour de valueAccessor() peut être observable ou non. C'est ce qui a été passé à la reliure.

139
RP Niemeyer

La réponse précédente est correcte, mais souvent, je passe des fonctions à des liaisons personnalisées (une fonction qui vérifie les autorisations ou détermine ce qu’elle doit faire en fonction de quelque chose d’autre, etc.). Ce dont j'avais vraiment besoin, c'était de décompresser n'importe quelle fonction, même si ce n'était pas observable.

Ce qui suit décompresse récursivement TOUT:

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

Voici un exemple de liaison personnalisée simple que j'ai écrite:

//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 cette manière, bindingValue contient toujours une valeur. Je n'ai pas besoin de m'inquiéter si je suis passé dans une fonction, une observable, une valeur ou même une fonction dans une observable. Cela va tout dérouler correctement jusqu'à ce qu'il atteigne l'objet que je veux.

J'espère que ça aide quelqu'un.

11
pilavdzice