A cosa servono i valori predefiniti di importazione / esportazione in un oggetto uiElement?


8

In molti dei costruttori del modello di vista Element dell'interfaccia utente di Magento 2, l' defaultsarray avrà una proprietà importso exports.

return Collection.extend({
    defaults: {
        //...
        imports: {
            rows: '${ $.provider }:data.items'
        },

return Insert.extend({
    defaults: {
        //...
        exports: {
            externalFiltersModifier: '${ $.externalProvider }:params.filters_modifier'
        },

Guardando la fonte del uiElementmodulo,

#File: vendor/magento/module-ui/view/base/web/js/lib/core/element/element.js
    initLinks: function () {
        return this.setListeners(this.listens)
                   .setLinks(this.links, 'imports')
                   .setLinks(this.links, 'exports')
                   .setLinks(this.exports, 'exports')
                   .setLinks(this.imports, 'imports');
    },

Queste importazioni / esportazioni sembrano avere qualcosa a che fare con il "collegamento" di informazioni tra oggetti quando un oggetto viene istanziato. Tuttavia, non è chiaro come funziona questo collegamento (basato su uiRegistry?) O come sono la sintassi per le stringhe ${ $.provider }:data.items. È chiaro che queste stringhe usano letterali template che si espandono in qualcosa del genere

foo_bar:data.items

Ma il significato di questa stringa finale è ancora misterioso.

Qualcuno sa come funzionano le proprietà di importazione / esportazione di questi oggetti?


Non pubblicherò una risposta dal momento che non li ho effettivamente utilizzati, ma i devdocs danno un po 'più di comprensione: devdocs.magento.com/guides/v2.1/ui-components/…
Vinai

Risposte:


21

Queste proprietà consentono ai componenti di essere collegati in modo che possano interagire tra loro. Il principio è piuttosto semplice: importare (prendere) un valore da un altro componente o esportare (inviare) un valore a un componente diverso o fare entrambi.


Nota: per mantenere la chiarezza in questa risposta, un "componente" è un oggetto Javascript che viene restituito da RequireJS, ha un nome specifico ed è possibile accedervi tramite UIRegistry.

Inoltre, tutti gli esempi seguenti sarebbero all'interno della defaults: {}proprietà del componente.


Con il principio stabilito, iniziamo con quello che considero il concetto più semplice:

importazioni

Questa proprietà prende un valore da un altro componente e lo assegna alla proprietà specificata. Nel seguente esempio, dichiariamo un'importazione:

imports: {
    message: '${ $.provider }:data.message'
}

Quando Magento inizializza questo componente, tenterà di assegnare il valore alla messageproprietà. Questa proprietà sarà disponibile nel contesto KnockoutJS. Come sappiamo , tuttavia, per prima cosa valuterà il imports.messagevalore come espressione letterale del modello. In questo caso, Magento analizzerà $.providere dovrebbe ottenere un valore. Mentre questo potrebbe essere un numero qualsiasi di cose, in questo esempio e secondo molti dei casi d'uso principali di Magento, è il nome di un componente che si trova nel registro dell'interfaccia utente. Questo verrà analizzato prima del passaggio successivo.

Poiché la messageproprietà si trova nella importsproprietà, verrà passata al setLinks()metodo in uiElement.initLinks(). Il setLinks()metodo è in Magento/Ui/view/base/web/js/lib/core/element/links.js. Lì, scorre su tutte le proprietà (solo messagequi) nell'oggetto che è stato passato in (imports in questo caso). Su tali proprietà, tenterà di trasferire i dati da un componente all'altro.

La transfer()funzione è il prossimo luogo di interesse. Qui, il registro viene cercato per il componente che è il "proprietario", nel caso di un'importazione. Questo componente è quello che attualmente "possiede" o ha i dati e sarebbe $.providernell'esempio sopra. Se viene trovato il componente, procederà quindi a collegare i dati con la setLink()funzione.

Ci sono due cose da notare in questo metodo: in primo luogo, imposta un listener di eventi sulla proprietà e, in secondo luogo, trasferirà immediatamente i dati se è stato inviato il flag applicabile. Nel mio test, ha sempre passato il immediateparametro in modo che il trasferimento avvenisse durante l'inizializzazione. Tuttavia, a causa del listener di eventi allegato nel primo passaggio, continuerà ad aggiornare i valori, se cambiano, in modo che entrambi i componenti rimangano sincronizzati.

I dati vengono quindi impostati sul (o, in termini più semplici: "restituito al") componente che aveva la imports: {}proprietà. Come accennato in precedenza, viene quindi assegnato direttamente alla proprietà del componente che lo ha dichiarato, essenzialmente this.messagenell'esempio precedente e non this.defaults.imports.message. Di conseguenza, data-bind="text: messagedovrebbe visualizzare il valore restituito dalla data.messageproprietà del componente collegato .

Questo approccio consente di definire quale sia il nome della proprietà nel componente di origine. Nell'esempio sopra, è possibile utilizzare alertMessage: ...invece messagecome nome della proprietà del componente.

esportazioni

Le esportazioni sono l'inverso di imports. Si basano sulla stessa funzionalità delle importazioni, ma invece di prendere i dati da un componente e assegnarli a se stesso, invia i propri dati a un altro componente. Di conseguenza, quasi tutto è l'opposto. Prendi questo esempio:

exports: {
    phoneNumber: '${ $.contactForm }:phone'
}

In questo esempio, setLinks()assume il valore della proprietà di questo componentephoneNumber e lo assegna alla phoneproprietà del modulo di contatto . È lo stesso che dichiarare esplicitamente una phoneproprietà nel $.contactFormcomponente. Senza alcuna impostazione particolare in $.contactForm, è quindi possibile accedere direttamente a questi dati. Forse in questo modo in un modello Knockout: data-bind="text: phone.

link

Infine, la linksproprietà è la stessa di dichiarare entrambi importse exportsper la stessa proprietà. A prima vista, questo può sembrare un riferimento circolare. Anche se in un certo senso, ci sono momenti in cui questo potrebbe essere utile. Mentre sono sicuro che ci sono molti altri casi d'uso, quello che posso vedere è la capacità di un componente di manipolare i dati da un altro componente in modo dinamico. In questo caso, ComponentA è la fonte di alcuni dati e li visualizza sulla pagina. Il componente B deve manipolare tali dati e quindi linkssu quella proprietà. Può sia visualizzare i dati sia manipolare i dati effettivi in ​​ComponentA senza mai estendere o modificare ComponentA.

Una cosa da notare, tuttavia, è che, per impostazione predefinita, linksnon sono un modo per collegare altri due moduli. In altre parole, ComponentC non può linkComponentA a ComponentB. È un metodo di sincronizzazione bidirezionale di un componente con un altro.


Collegamento ( imports, exports, e links) può quasi sempre facilitare funzioni assegnate a tali proprietà pure. Mi sono imbattuto in uno strano comportamento durante la creazione di osservabili e l'utilizzo linksma nel complesso ha funzionato abbastanza bene.

Il collegamento fornisce valori che sono disponibili nell'ambito di KnockoutJS e possono essere manipolati come qualsiasi altra proprietà. E, per ribadire in modo chiaro: ricordare che il imports, exportselinks dell'oggetto chiavi si riferiscono sempre alla proprietà del componente corrente (quella in cui sono stati dichiarati tali proprietà), mentre gli appartiene valore al nome e le proprietà del componente remoto .


In conclusione, Magento utilizza questa funzionalità di collegamento per connettere diversi componenti tra loro ed è un modo in cui possiamo accedere, fornire o sincronizzare i dati con altri componenti.


Grande spiegazione @ bassplayer7 - Hai qualche esempio di questo? Capisco come funziona ma per la mia vita non riesco a ottenere due dei miei semplici componenti dell'interfaccia utente per condividere un KO osservabile.
Ben Crook,

@BenCrook, sfortunatamente, non ho fatto molto con questo per un po ', quindi non ne ho uno subito. Ormai sono sicuro che l'hai capito, ma suggerisco di lavorare con importse exportspiuttosto che links. Ho scoperto linksdi essere più oscuro e fragile. Se hai trovato un esempio, potresti condividere un link?
bassplayer7,

Ho provato e non riesco a far funzionare le importazioni / esportazioni / collegamenti, Vinai ha risposto alla domanda qui, anche se non ho ancora avuto modo di provarlo.
Ben Crook,

Questa informazione sarebbe ottima sui documenti di sviluppo ufficiali. Il processo di UI Cmponent è solo una bestia spaventosa.
Nathaniel Rogers,
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.