Pour comprendre ce que checkoutProvider
et displayArea
sont, vous devez d' abord comprendre la portée que vous êtes à la recherche dans: jsLayout
.
jsLayout
est 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 leMagento_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/app
composant (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.js
tout se résume, car cela rendrait ce message très, très long, mais le résumé est le suivant:
Magento_Ui/js/core/app
-component crée un checkout
-component.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).Magento_Checkout/web/frontend/template/onepage.html
.errors
, estimation
, steps
, etc ...)steps
enfant sera également un uiComponent
.Passons maintenant à votre displayArea
et 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 displayArea
c'est lorsque nous créons le steps
-component, qui est du type uiComponent
. Ce uiComponent
serait donc un candidat logique à rechercher displayArea
.
Maintenant, a uiComponent
est 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 phtml
modè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 provider
est utilisé dans cette classe. Voyons donc si nous pouvons trouver quoi que ce soit dans la classe qu'il étend: Component
(qui est à uiComponent
nouveau notre classe).
Mais ... non provider
aussi. 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 shippingAddress
est 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:
checkoutProvider
défini?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.
6 mois après ma réponse d'origine, je pense que je peux fournir une meilleure réponse sur ce qui
displayArea
est.À ma connaissance, tout cela vient avec la
getTemplate()
méthode- Knockouts , lagetRegion()
méthode-et les enfants dans les composants d'interface utilisateur. Un bon exemple de cela peut être vu lorsque vous examinezvendor/magento/module-checkout/view/frontend/templates/registration.phtml
etvendor/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:Notez l'utilisation de
displayArea
dans lechildren
-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
: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?
la source
getRegion
et mon esprit implose. Merci pour les deux réponses d'ailleurs, très utiles!