Was bedeuten "displayArea" und "provider" von checkout_index_index.xml in magento2?


Antworten:


22

Um zu verstehen , was checkoutProviderund displayAreasind, müssen Sie zunächst den Umfang verstehen , die Sie suchen in: jsLayout.

jsLayoutist eine Sammlung von JavaScript-Konfigurationen für die JavaScript-Benutzeroberflächenelemente auf der Checkout-Seite. Wenn Sie sich das ansehen module-checkout/view/frontend/templates/onepage.phtml, werden Sie die folgenden x-magento-initDaten bemerken:

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

Hier fängt alles an. Es sagt aus:

#checkoutInitialisieren Sie für element die Magento_Ui/js/core/app-Komponente mit den folgenden Informationen: ...

Und die Informationen , die sie erhält , ist die Information in dem Layout - XML erstellt: jsLayout. Das bedeutet, dass jetzt alles in Ihrem XML- Magento_Ui/js/core/appCode an die -Komponente übergeben wird (Plugins, Layoutprozessoren und ähnliches bleiben vorerst unberücksichtigt ...)

Ich werde jetzt nicht näher darauf eingehen, wie sich module-ui/view/base/web/js/core/app.jsalles zusammensetzt, denn das würde diesen Beitrag sehr, sehr lang machen, aber die Zusammenfassung lautet wie folgt:

  • Die Magento_Ui/js/core/app-Komponente erzeugt eine checkout-Komponente.
  • Dies ist eine Komponente des Typs uiComponent(dies ist eine sehr generische Komponente, mit der Sie Ihre eigenen benutzerdefinierten UI-Komponenten von diesem Typ entfernen können. Sie enthält grundlegende Funktionen zum Rendern von Knockout-Vorlagen und ähnliches).
  • Es wird uns die Vorlage geben Magento_Checkout/web/frontend/template/onepage.html.
  • Es werden verschiedene Kinder schaffen (mit dem Namen errors, estimation, steps, etc ...)
  • Das steps-Kind wird auch ein uiComponent.
  • Dieser Zyklus geht weiter ... die Konfiguration macht Kinder mit verschiedenen Parametern.

Nun zu Ihrer displayAreaund provider-Frage: Wie Sie oben gesehen haben, ist alles JavaScrip-Klassen zugeordnet. Das erste Mal sehen wir die Verwendung von, displayAreawenn wir die steps-Komponente erstellen , die vom Typ ist uiComponent. Wäre uiComponentalso ein logischer Kandidat, nach der Verwendung zu suchen displayArea.

Nun ist a uiComponenteine JavaScript-Klasse des Typs Magento_Ui/js/lib/core/collection. (Sie können dies in nachschlagen module-ui/view/base/requirejs-config.js). Dies entspricht module-ui/view/base/web/js/lib/core/collection.js. Hier sehen wir die folgende Verwendung:

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

Das bedeutet, dass eine uiComponent einer bestimmten Gruppe von UI-Komponenten zugeordnet wird. Dies ist wichtig zu wissen, da es uns ermöglicht, UI-Komponenten an andere Positionen im Layout zu verschieben, indem Sie einfach das XML-Layout bearbeiten, genau wie Sie dies mit phtmlVorlagen tun würden , die serverseitig gerendert werden. Wenn Sie das überschreiben displayArea, können Sie eine beliebige JavaScript-UI-Komponente an einer anderen Stelle rendern (vorausgesetzt, der Zielbereich wird auch irgendwo gerendert).

Nun zu Ihrer zweiten Frage: provider. Genauso wie wir nachgesehen haben displayArea, sollten wir uns zuerst die UI-Komponente ansehen Magento_Checkout/js/view/form/element/email. Und wenn wir uns das anschauen requirejs-config.js, finden wir endlich module-checkout/view/frontend/web/js/view/form/element/email.js.

Aber ... nein providerwird in dieser Klasse verwendet. Schauen wir also mal, ob wir irgendetwas in der Klasse finden können, die es erweitert: Component(das ist wieder unsere uiComponentKlasse).

Aber ... nein providerauch. Naja, uiComponenteinfach ausdehnen Element(was sich auf befindet module-ui/view/base/web/js/lib/core/element/element.js), also lasst uns einfach dort hinüber schauen:

/**
 * 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! Es stellt sich heraus, dass der Anbieter als Quelle zum Abrufen von Daten verwendet wird. Wenn wir uns den Konstruktor von ansehen Element, werden Sie feststellen, dass er standardmäßig leer ist:

provider: '',

Also zurück zu unserer Konfiguration. Wenn wir jetzt unsere Konfiguration lesen, werden wir verstehen, dass das Element shippingAddresseine Komponente von ist Magento_Checkout/js/view/shipping, die seine Daten aus dem abruft checkoutProvider.

Das lässt uns also zwei Fragen offen:

  1. Wo ist checkoutProviderdefiniert?
  2. Wie wird es im Versand-JavaScript verwendet?

Wenn Sie nach unten scrollen checkout_index_index.xml, werden Sie feststellen, dass es sich nur um eine Vanille handelt uiComponent:

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

Und wenn Sie sich das ansehen module-checkout/view/frontend/web/js/view/shipping.js, werden Sie feststellen, dass es so verwendet wird:

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

Um ehrlich zu sein: Hier hört meine Analyse auf, weil es für mich auch schwierig wird zu suchen und zu investieren, was los ist, aber ich hoffe, jemand anderes kann es hier abholen ...

Ich weiß, es hat etwas mit der registry.async()Rückgabe einer Methode zu tun, die sofort mit einer Rückruffunktion als Argument ausgeführt wird, aber jemand anderes muss dies erklären ...


* Haftungsausschluss: Bitte korrigieren Sie mich auf jeden Fall, wenn ich falsch liege! Ich habe noch keine der oben genannten Möglichkeiten ausprobiert, aber ich arbeite seit fast einem Jahr mit Magento 2 und glaube, dass dies so funktioniert. Leider gibt es nicht viel Dokumentation, wenn Sie auf den Grund des Magento-Ozeans tauchen möchten.


2
Was ist DisplayArea?
Marián Zeke Šedaj

1
Das ist eine brillante Analyse. Haben Sie jemals ein weiteres Verständnis entwickelt?
LM_Fielding

11

6 Monate nach meiner ursprünglichen Antwort denke ich, dass ich eine bessere Antwort auf das geben kann, was displayAreaist.

Meines getTemplate()Erachtens getRegion()hängt dies alles mit der Knockout- Methode, der -Methode und den untergeordneten Elementen in den UI-Komponenten zusammen. Ein gutes Beispiel hierfür ist bei der Prüfung von vendor/magento/module-checkout/view/frontend/templates/registration.phtmlund zu sehen vendor/magento/module-checkout/view/frontend/web/template/registration.html.

In sehen registration.phtmlSie eine Standard-Magento-UI-Komponente mit untergeordneten Elementen:

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

Beachten Sie die Verwendung von displayAreaim children-Node. Grundsätzlich wird Knockout mitgeteilt, dass dieses untergeordnete Element in einem Bereich mit dem Namen "messages" gerendert werden soll .

Schauen Sie sich jetzt oben an registration.html:

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

Grundsätzlich bewirkt diese Zeile des Knockout-Codes Folgendes: Sie durchläuft alle untergeordneten Elemente, die in den displayArea -Nachrichten enthalten sind , und rendert sie.

Grundsätzlich ist die Benennung etwas verwirrend, wenn Sie mich fragen. Warum sollten Sie "displayArea" an einem Ort und "region" an einem anderen Ort verwenden ? Aber vielleicht ist meine Annahme völlig falsch. Vielleicht könnte ein Magento-Kernentwickler etwas mehr Licht ins Dunkel bringen?


1
Das ist es, was mich so lange verwirrt hat, ich sehe weiter getRegionund mein Verstand implodiert einfach. Danke übrigens für beide Antworten, sehr hilfreich!
Ben Crook

1
Nun, das sind nur meine 2 Cent. Ich hoffe, dass jemand von den Kernentwicklern etwas Licht in dieses Thema bringen kann. Die tieferen Interna von Magento 2 und insbesondere die gesamte Knockout / XHR-Implementierung sind etwas, das nicht so gut dokumentiert wurde.
Giel Berkers

2
Einverstanden, es sei denn, Sie vertiefen sich in viele der Kerndateien, gibt es so gut wie keine andere Möglichkeit als diesen Stapelaustausch, um zu wissen, was zum Teufel los ist.
Ben Crook
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.