Quando usare ko.utils.unwrapObservable?


114

Ho scritto alcune associazioni personalizzate usando KnockoutJS. Non sono ancora sicuro di quando usare ko.utils.unwrapObservable(item)Looking at the code, quella chiamata controlla fondamentalmente per vedere se itemè un osservabile. Se lo è, restituisci il valore (), se non lo è, restituisci semplicemente il valore. Guardando la sezione su Knockout sulla creazione di associazioni personalizzate, hanno la seguente sintassi:

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

In questo caso, invocano l'osservabile via ()ma poi chiamano anche ko.utils.unwrapObservable. Sto solo cercando di capire quando usare l'uno o l'altro o se dovrei seguire sempre lo schema sopra e usare entrambi.

Risposte:


142

Dovresti usare ko.utils.unwrapObservablenei casi in cui non sai se ti è stato dato un osservabile o meno. Questo sarebbe comunemente in un'associazione personalizzata in cui un osservabile o un non osservabile potrebbe essere associato ad esso.

Nel codice che hai sopra, la chiamata a valueAccessor()non sta effettivamente scartando un osservabile. Sta solo recuperando il valore passato all'associazione nel contesto corretto (viene racchiuso in una funzione per proteggerlo). Il valore restituito di valueAccessor()può essere osservabile o meno. È tutto ciò che è stato passato all'associazione.


4
Dipende davvero dalla situazione. Alcuni binding personalizzati sono progettati per funzionare solo con osservabili, quindi puoi controllare in anticipo (ko.isObservable) che sia osservabile e poi sarai libero di scartarlo con (). Se stai ricevendo un oggetto che potrebbe avere osservabili annidati, allora è meglio fare un ko.toJS(yourObject)piuttosto che usare ko.utils.unwrapObservable, se stai cercando di ottenere una versione non incartata dell'oggetto da passare in un widget o in una libreria di terze parti. In generale, è più sicuro da usare ko.utils.unwrapObservableper supportare osservabili e non osservabili.
RP Niemeyer

2
Immagino di essere confuso con quale sia lo scopo ko.utils.unwrapObservable. Guardando il codice, controlla solo per vedere se è osservabile e, in tal caso, Knockout invoca ()per ottenere il valore dell'osservabile, altrimenti restituisce semplicemente il valore per non osservabile. Se tutto ciò che mi interessa è il valore dei dati passati nell'associazione, perché non posso usarlo sempre ()?
arb

17
Non sai se stai ricevendo un osservabile o un non osservabile in un'associazione. Dì che l'ho fatto myBindinge qualcuno si lega cioè come data-bind="myBinding: myValue". myValuepotrebbe essere un osservabile o potrebbe essere solo una proprietà semplice sul modello di visualizzazione. Se è solo una proprietà e la chiamo come una funzione, verrà visualizzato un errore. ko.utils.unwrapObservableti restituirà in sicurezza il valore indipendentemente dal fatto che ti sia stato passato un osservabile o meno.
RP Niemeyer

10
Consiglio anche di usare la scorciatoia "ko.unwrap" perché "ko.utils.unwrapObservable" è un'espressione molto lunga.
Ivan Nikitin

3
@IvanNikitin - certo, volevo solo sottolineare che ko.unwrapè disponibile in 3.0+. Se stai usando una versione precedente alla 3.0, allora ko.utils.unwrapObservableè ancora lì.
RP Niemeyer

12

La risposta precedente è corretta, ma spesso passo le funzioni alle associazioni personalizzate (una funzione che controlla i permessi o determina cosa fare in base a qualcos'altro, ecc.). Quello di cui avevo veramente bisogno era scartare qualsiasi funzione, anche se non è osservabile.

Il seguente scartare ricorsivamente TUTTO:

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

Ecco un esempio di una semplice associazione personalizzata che ho scritto:

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

In questo modo bindingValue contiene sempre un valore. Non ho bisogno di preoccuparmi se ho passato una funzione, un osservabile, un valore o anche una funzione all'interno di un osservabile. Questo scarterà correttamente tutto finché non arriva all'oggetto che voglio.

Spero che aiuti qualcuno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.