cosa significano "displayArea" e "provider" di checkout_index_index.xml in magento2


Risposte:


22

Per capire cosa checkoutProvidere displayAreasono, è necessario prima capire la portata si sta cercando in: jsLayout.

jsLayoutè un gruppo di configurazioni JavaScript per gli elementi dell'interfaccia utente JavaScript nella pagina di pagamento. Se guardi module-checkout/view/frontend/templates/onepage.phtml, noterai i seguenti x-magento-initdati:

<script type="text/x-magento-init">
    {
        "#checkout": {
            "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?>
        }
    }
</script>

Questo è dove tutto comincia. Afferma:

Per l'elemento #checkout, inizializza il componente Magento_Ui/js/core/appcon le seguenti informazioni: ...

E le informazioni che riceve sono le informazioni creata nel XML di layout: jsLayout. Ora, questo significa che tutto nel tuo XML è ora passato al componente Magento_Ui/js/core/app(lasciando plugin, processori di layout e cose fuori dall'equazione per il momento ...)

Ora, non approfondirò il modo in cui module-ui/view/base/web/js/core/app.jstutto si riduce, perché ciò renderebbe questo post molto, molto lungo, ma il riassunto è questo:

  • Il componente Magento_Ui/js/core/appcrea un componente checkout.
  • Questo sarà un componente del tipo uiComponent(questo è un componente molto generico che può essere utilizzato per rinviare i tuoi componenti personalizzati dell'interfaccia utente. Viene fornito con il rendering del modello knockout di base e altro).
  • Ci sarà il modello Magento_Checkout/web/frontend/template/onepage.html.
  • Si creerà vari bambini (con il nome errors, estimation, steps, ecc ...)
  • Il stepsbambino sarà anche a uiComponent.
  • Questo ciclo continua ... la configurazione rende i bambini con vari parametri.

Ora per raggiungere la vostra displayAreae provider-question: Come si è visto sopra, tutto mappe alle classi JavaScrip. La prima volta che vediamo l'uso di displayAreaè quando creiamo il componente steps, che è del tipo uiComponent. Quindi uiComponentsarebbe un candidato logico per cercare l'uso di displayArea.

Ora, a uiComponentè una classe JavaScript del tipo Magento_Ui/js/lib/core/collection. (Puoi cercarlo in module-ui/view/base/requirejs-config.js). Questo è mappato a module-ui/view/base/web/js/lib/core/collection.js. Qui vediamo il seguente uso:

/**
 * Synchronizes multiple elements arrays with a core '_elems' container.
 * Performs elemets grouping by theirs 'displayArea' property.
 * @private
 *
 * @returns {Collection} Chainable.
 */
_updateCollection: function () {
    var _elems = compact(this._elems),
        grouped;

    grouped = _elems.filter(function (elem) {
        return elem.displayArea && _.isString(elem.displayArea);
    });
    grouped = _.groupBy(grouped, 'displayArea');

    _.each(grouped, this.updateRegion, this);

    this.elems(_elems);

    return this;
},

Quindi, ciò che fa in effetti, "associa" un componente ui a un determinato gruppo di componenti dell'interfaccia utente. Questo è importante da sapere, perché ci consente di spostare i componenti dell'interfaccia utente in altre posizioni nel layout, semplicemente manipolando il layout XML, proprio come faresti con i phtmlmodelli resi sul lato server. Sostituisci semplicemente displayAreae puoi renderizzare qualsiasi componente dell'interfaccia utente JavaScript altrove (dato che anche l'area di destinazione viene renderizzata da qualche parte).

Ora per la tua seconda domanda: provider. Proprio come abbiamo cercato displayArea, dovremmo iniziare a guardare prima il componente UI, che è Magento_Checkout/js/view/form/element/email. E se guardiamo il requirejs-config.js, finalmente troviamo module-checkout/view/frontend/web/js/view/form/element/email.js.

Ma ... no providerè usato in questa classe. Quindi vediamo solo se riusciamo a trovare qualcosa nella classe che estende: Component(che è di uiComponentnuovo la nostra classe).

Ma ... no providerpure. Bene, uiComponentsi estende semplicemente Element(che si trova in module-ui/view/base/web/js/lib/core/element/element.js), quindi diamo un'occhiata qui:

/**
 * Parses 'modules' object and creates
 * async wrappers for specified components.
 *
 * @returns {Element} Chainable.
 */
initModules: function () {
    _.each(this.modules, function (name, property) {
        if (name) {
            this[property] = this.requestModule(name);
        }
    }, this);

    if (!_.isFunction(this.source)) {
        this.source = registry.get(this.provider);
    }

    return this;
},

Bingo! Si scopre che il provider viene utilizzato come fonte da cui recuperare i dati. Se guardiamo il costruttore di Element, vedrai che per impostazione predefinita, è impostato su vuoto:

provider: '',

Quindi torniamo alla nostra configurazione. Se ora leggiamo la nostra configurazione, capiremo che l'elemento shippingAddressè un componente di Magento_Checkout/js/view/shipping, che recupera i suoi dati da checkoutProvider.

Quindi questo ci lascia con due domande:

  1. Dove è checkoutProviderdefinito?
  2. Come viene utilizzato nel JavaScript di spedizione?

Bene, se scorri fino in fondo checkout_index_index.xml, noterai che non è altro che una vaniglia uiComponent:

<item name="checkoutProvider" xsi:type="array">
    <item name="component" xsi:type="string">uiComponent</item>
</item>

E se guardi module-checkout/view/frontend/web/js/view/shipping.js, vedrai che è usato in questo modo:

registry.async('checkoutProvider')(function (checkoutProvider) {
    var shippingAddressData = checkoutData.getShippingAddressFromData();

    if (shippingAddressData) {
        checkoutProvider.set(
            'shippingAddress',
            $.extend({}, checkoutProvider.get('shippingAddress'), shippingAddressData)
        );
    }
    checkoutProvider.on('shippingAddress', function (shippingAddressData) {
        checkoutData.setShippingAddressFromData(shippingAddressData);
    });
});

Ad essere sincero: è qui che la mia analisi si interrompe, perché per me diventa anche difficile cercare e investire ciò che sta succedendo, ma spero che qualcun altro possa raccoglierlo da qui ...

So che ha qualcosa a che fare con la registry.async()restituzione di un metodo che viene immediatamente eseguito con una funzione di callback come argomento, ma qualcun altro deve spiegare questo ...


* Disclaimer: per favore correggimi se sbaglio! Non ho mai provato nessuno dei precedenti, ma ho lavorato per quasi un anno con Magento 2 e credo che sia così. Sfortunatamente non c'è molta documentazione se vuoi immergerti sul fondo dell'Oceano Magento.


2
quindi cos'è displayArea?
Marián Zeke Šedaj,

1
Questa è un'analisi brillante, hai mai sviluppato un'ulteriore comprensione?
LM_Fielding

11

6 mesi dopo la mia risposta originale, penso di poter fornire una risposta migliore su ciò che displayAreaè.

Da quanto ho capito, tutto si combina con il getTemplate()metodo di Knockout , il getRegion()metodo e i bambini in UI Components. Un buon esempio di questo può essere visto quando stai esaminando vendor/magento/module-checkout/view/frontend/templates/registration.phtmle vendor/magento/module-checkout/view/frontend/web/template/registration.html.

In registration.phtml, vedrai un componente predefinito dell'interfaccia utente di Magento con figli:

<script type="text/x-magento-init">
    {
        "#registration": {
            "Magento_Ui/js/core/app": {
               "components": {
                    "registration": {
                        "component": "Magento_Checkout/js/view/registration",
                        "config": {
                            "registrationUrl": "<?php /* @escapeNotVerified */ echo $block->getCreateAccountUrl(); ?>",
                            "email": "<?php /* @escapeNotVerified */ echo $block->getEmailAddress(); ?>"
                        },
                        "children": {
                            "errors": {
                                "component": "Magento_Ui/js/view/messages",
                                "sortOrder": 0,
                                "displayArea": "messages",
                                "config": {
                                    "autoHideTimeOut": -1
                                 }
                            }
                        }
                    }
                }
            }
        }
    }
</script>

Nota l'uso di displayAreain children-node. Fondamentalmente, dice a Knockout che questo elemento figlio dovrebbe essere reso in una regione chiamata 'messaggi' .

Ora dai un'occhiata in cima a registration.html:

<!-- ko foreach: getRegion('messages') -->
    <!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->

Ciò che questa riga di codice Knockout sostanzialmente fa è: scorre su tutti gli elementi figlio presenti nei "messaggi" di displayArea e li rende.

Fondamentalmente, la denominazione è un po 'confusa se me lo chiedi. Perché dovresti usare "displayArea" in un posto e "regione" in un altro posto? Ma forse la mia ipotesi è totalmente errata. Forse uno sviluppatore di core Magento potrebbe far luce su questo?


1
Questo è ciò che mi ha confuso per così tanto tempo, continuo a vedere getRegione la mia mente implode. Grazie per entrambe le risposte, molto utile!
Ben Crook,

1
Bene, questi sono solo i miei 2 centesimi. Spero che qualcuno degli sviluppatori principali possa condividere un po 'di luce su questo argomento. Gli interni più profondi di Magento 2, e in particolare l'intera implementazione Knockout / XHR, sono qualcosa che non è stato così ben documentato.
Giel Berkers,

2
D'accordo, a meno che non si analizzi molti dei file principali, non c'è praticamente altro che questo scambio di stack per sapere cosa diavolo sta succedendo.
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.