que signifie "displayArea" et "provider" de checkout_index_index.xml dans magento2

22

entrez la description de l'image ici

qu'est-ce displayAreaet providerde checkout_index_index.xmlmoyenne en magento2?

LifeAsBook
la source

Réponses:

22

Pour comprendre ce que checkoutProvideret displayAreasont, vous devez d' abord comprendre la portée que vous êtes à la recherche dans: jsLayout.

jsLayoutest un tas de configuration JavaScript pour les éléments de l'interface utilisateur JavaScript sur la page de paiement. Si vous regardez module-checkout/view/frontend/templates/onepage.phtml, vous remarquerez les données suivantes x-magento-init:

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

C'est là que tout commence. Il est dit:

Pour l'élément #checkout, initialisez le Magento_Ui/js/core/app-component avec les informations suivantes: ...

Et les informations qu'il reçoit est l'information créée dans le fichier XML de mise en page: jsLayout. Maintenant, cela signifie que tout dans votre XML est maintenant transmis au Magento_Ui/js/core/appcomposant (laissant les plugins et les processeurs de mise en page et tout cela hors de l'équation pour le moment ...)

Maintenant, je ne vais pas plonger dans les détails sur la façon dont module-ui/view/base/web/js/core/app.jstout se résume, car cela rendrait ce message très, très long, mais le résumé est le suivant:

  • Le Magento_Ui/js/core/app-component crée un checkout-component.
  • Ce sera un composant du type uiComponent(c'est un composant très générique qui peut être utilisé pour différer vos propres composants d'interface utilisateur personnalisés. Il est livré avec un rendu de modèle de knockout de base et d'autres choses).
  • Il nous servira de modèle Magento_Checkout/web/frontend/template/onepage.html.
  • Il permettra de créer différents enfants (avec le nom errors, estimation, steps, etc ...)
  • L' stepsenfant sera également un uiComponent.
  • Ce cycle continue ... la configuration fait des enfants avec différents paramètres.

Passons maintenant à votre displayAreaet provider-question: Comme vous l'avez vu ci-dessus, tout est mappé aux classes JavaScrip. La première fois que nous voyons l'utilisation de displayAreac'est lorsque nous créons le steps-component, qui est du type uiComponent. Ce uiComponentserait donc un candidat logique à rechercher displayArea.

Maintenant, a uiComponentest une classe JavaScript du type Magento_Ui/js/lib/core/collection. (Vous pouvez le rechercher module-ui/view/base/requirejs-config.js). Cela correspond à module-ui/view/base/web/js/lib/core/collection.js. Ici, nous voyons l'utilisation suivante:

/**
 * 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;
},

Donc, ce que cela fait, il «mappe» un uiComponent à un certain groupe de composants d'interface utilisateur. C'est important à savoir, car cela nous permet de déplacer des composants d'interface utilisateur vers d'autres emplacements de la mise en page, en manipulant simplement la mise en page XML, tout comme vous le feriez avec des phtmlmodèles rendus côté serveur. Remplacez simplement le displayArea, et vous pouvez rendre n'importe quel composant d'interface utilisateur JavaScript ailleurs (étant donné que la zone cible est également rendue quelque part).

Maintenant , pour votre deuxième question: provider. Tout comme nous avons recherché displayArea, nous devrions commencer par examiner le composant d'interface utilisateur, ce qui est Magento_Checkout/js/view/form/element/email. Et si nous regardons le requirejs-config.js, nous trouvons enfin module-checkout/view/frontend/web/js/view/form/element/email.js.

Mais ... non providerest utilisé dans cette classe. Voyons donc si nous pouvons trouver quoi que ce soit dans la classe qu'il étend: Component(qui est à uiComponentnouveau notre classe).

Mais ... non provideraussi. Eh bien, uiComponentétend simplement Element(qui se trouve à module-ui/view/base/web/js/lib/core/element/element.js), alors regardons là-bas:

/**
 * 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! Il s'avère que le fournisseur est utilisé comme source pour récupérer des données. Si nous regardons le constructeur de Element, vous verrez que par défaut, il est défini sur vide:

provider: '',

Revenons donc à notre configuration. Si nous lisons maintenant notre configuration, nous comprendrons que l'élément shippingAddressest un composant de Magento_Checkout/js/view/shipping, qui récupère ses données à partir du checkoutProvider.

Cela nous laisse donc avec deux questions:

  1. Où est checkoutProviderdéfini?
  2. Comment est-il utilisé dans le JavaScript d'expédition?

Eh bien, si vous faites défiler vers le bas checkout_index_index.xml, vous remarquerez que ce n'est rien de plus qu'une vanille uiComponent:

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

Et si vous regardez module-checkout/view/frontend/web/js/view/shipping.js, vous verrez qu'il est utilisé comme ceci:

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);
    });
});

Pour être honnête: c'est là que mon analyse s'arrête, car il devient aussi difficile pour moi de rechercher et d'investir ce qui se passe, mais j'espère que quelqu'un d'autre pourra le récupérer d'ici ...

Je sais que cela a quelque chose à voir avec le registry.async()retour d'une méthode qui est immédiatement exécutée avec une fonction de rappel comme argument, mais quelqu'un d'autre doit expliquer cela ...


* Avertissement: Bien sûr, corrigez-moi si je me trompe! Je n'ai vraiment rien essayé de ce qui précède, mais je travaille presque depuis un an avec Magento 2 et je pense que c'est ainsi que cela fonctionne. Malheureusement, il n'y a pas beaucoup de documentation si vous voulez plonger au fond de l'océan Magento.

Giel Berkers
la source
2
alors qu'est-ce que displayArea?
Marián Zeke Šedaj
1
C'est une analyse brillante, avez-vous déjà développé une meilleure compréhension?
LM_Fielding
11

6 mois après ma réponse d'origine, je pense que je peux fournir une meilleure réponse sur ce qui displayAreaest.

À ma connaissance, tout cela vient avec la getTemplate()méthode- Knockouts , la getRegion()méthode-et les enfants dans les composants d'interface utilisateur. Un bon exemple de cela peut être vu lorsque vous examinez vendor/magento/module-checkout/view/frontend/templates/registration.phtmlet vendor/magento/module-checkout/view/frontend/web/template/registration.html.

Dans registration.phtml, vous verrez un composant d'interface utilisateur Magento par défaut qui a des enfants:

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

Notez l'utilisation de displayAreadans le children-node. Fondamentalement, il indique à Knockout que cet élément enfant doit être rendu dans une région appelée «messages» .

Jetez maintenant un œil en haut de registration.html:

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

Ce que cette ligne de code Knockout fait, c'est: elle itère tous les éléments enfants qui sont présents dans les «messages» displayArea et les rend.

Fondamentalement, la dénomination est un peu déroutante si vous me demandez. Pourquoi utiliseriez-vous «displayArea» à un endroit et «region» à un autre endroit. Mais peut-être que mon hypothèse est totalement incorrecte. Peut-être qu'un développeur principal de Magento pourrait éclairer un peu plus ce sujet?

Giel Berkers
la source
1
C'est ce qui m'a dérouté pendant si longtemps, je continue de voir getRegionet mon esprit implose. Merci pour les deux réponses d'ailleurs, très utiles!
Ben Crook
1
Eh bien, c'est juste mes 2 cents. J'espère que quelqu'un des développeurs principaux pourra partager un peu de lumière sur ce sujet. Les internes plus profonds de Magento 2, et en particulier l'ensemble de l'implémentation Knockout / XHR, sont quelque chose qui n'a pas été si bien documenté.
Giel Berkers
2
D'accord, à moins que vous ne plongiez dans de nombreux fichiers de base, il n'y a pratiquement pas d'autre moyen que cet échange de pile pour savoir ce qui se passe.
Ben Crook