Come condividere osservabili Knockout JS tra i componenti dell'interfaccia utente


12

Comprendo come utilizzare imports: {}eexports: {} condividere le proprietà dei componenti di un'interfaccia utente, come ad esempio:

defaults: {
    exports: {
        shouldShowMessage: '${$.component}'
    }
}

Che restituisce il nome del componente nelle esportazioni.

inserisci qui la descrizione dell'immagine

Ma quando provo ad esportare un Knockout osservabile è sempre indefinito:

defaults: {
    exports: {
        shouldShowMessage: '${$.shouldShowMessage}'
    }
}

...

setupKoBindings: function() {
    this.shouldShowMessage = ko.observable('Testing');
}

inserisci qui la descrizione dell'immagine

Per ovviare al problema, creerò un modello di archiviazione come spiegato qui, ma preferirei utilizzare le importazioni e le esportazioni.

Risposte:


12

I valori dell'oggetto export devono essere risolti in un nome e una proprietà di un'istanza UiComponent, separati da un ':', ad esempio checkout.cart.total:title.
Il nome della destinazione di esportazione deve includere lo "spazio dei nomi" del componente UI.

Nel tuo esempio, imposti il ​​valore su una stringa, che si risolve in una proprietà di UiComponent che è l'origine di esportazione. L'esportazione non è definita quando la si ispeziona perché non si tratta di una destinazione di esportazione valida.

Ecco un esempio che funziona:

defaults: {
    exportTarget: "foo.bar",
    exportTargetProperty: "showMessage",

    tracks: {
        shouldShowMessage: true
    },

    exports: {
        shouldShowMessage: '${$.exportTarget}:${$.exportTargetProperty}'
    }
}
...

Quanto sopra copierà il valore della shouldShowMessageproprietà nella proprietà showMessagedi un UiComponent con il nome completo foo.barogni volta che il valore cambia.
Si noti che ciò non renderà automaticamente osservabile anche la proprietà target. Ciò deve essere dichiarato esplicitamente, se le modifiche al valore devono attivare KO per il rendering dei nodi DOM che accedono a quella proprietà.

A proposito, aggiungendo shouldShowMessagealla tracksoggetto renderà un ko-ES5 automagically osservabile. Usare anche ko.observable()opere letterali .

Nell'esempio sopra, exportTargete exportTargetPropertysono configurati in defaults. Potrebbero anche essere specificati come parte delle opzioni UiComponent in JSON, il che di solito ha più senso, poiché è qui che vengono definite la gerarchia di UiComponent che include i nomi UiComponent.

Infine, vorrei notare che personalmente ritengo che la soluzione che utilizza un oggetto valore per passare il valore all'altro componente dell'interfaccia utente sia migliore dell'utilizzo di esportazioni o importazioni. Nella mia esperienza, mantenere lo stato condiviso nel DOM o in UiComponents è una ricetta per spaghetti OOP in tutti tranne che nei casi più semplici.


Ottima spiegazione, grazie @Vinai! Ci proverò quando avrò tempo e lo segnerò come accettato se funziona.
Ben Crook,

Ho riscontrato alcuni problemi durante l'utilizzo tracks, la sottoscrizione manuale agli osservabili non funziona più this.shouldShowMessage.subscribe is not a functionquando si utilizza this.shouldShowMessage.subscribe(function() { ... }); Funziona bene quando si imposta osservabili in altro modo. Mi trackssembra di perdere un passo o di non creare un osservabile allo stesso modo.
Ben Crook,

Hai ragione, le proprietà non sono più normali osservabili ko, solo coppie getter / setter ES5. Se vuoi accedere alla funzione osservabile originale puoi iniettare ko e usare ko.getObservable(this, 'shouldShowMessage').subscribe(function(newValue) { ...});(il primo argomento è viewmodel ( this), il secondo il nome della proprietà monitorata. Maggiori informazioni qui: github.com/SteveSanderson/knockout-es5
Vinai

Ahh, ha senso, sei il migliore <3
Ben Crook,

1
Dopo aver giocato con le importazioni e le esportazioni e ancora fallendo, sono d'accordo che questo è il codice spaghetti, ho rinunciato e seguirò abbonamenti manuali e un modello di archiviazione.
Ben Crook,
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.