co oznacza „displayArea” i „dostawca” checkout_index_index.xml w magento2

22

wprowadź opis zdjęcia tutaj

co robi displayAreai providerod checkout_index_index.xmlśredniej w magento2?

LifeAsBook
źródło

Odpowiedzi:

22

Aby zrozumieć, co checkoutProvideri displayAreasą, trzeba najpierw zrozumieć zakres szukasz w: jsLayout.

jsLayoutto kilka konfiguracji JavaScript dla elementów interfejsu użytkownika JavaScript na stronie kasy. Jeśli spojrzysz na to module-checkout/view/frontend/templates/onepage.phtml, zauważysz następujące x-magento-initdane:

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

Od tego wszystko się zaczyna. W Stanach:

Dla elementu #checkoutzainicjuj Magento_Ui/js/core/app-component następującymi informacjami: ...

A informacje otrzymuje się informacje tworzone w XML układ: jsLayout. Oznacza to, że wszystko w twoim XML jest teraz przekazywane do Magento_Ui/js/core/app-komponentu (pozostawiając wtyczki, procesory układu i inne rzeczy poza równaniem na razie ...)

Teraz nie będę zagłębiał się w szczegóły, jak module-ui/view/base/web/js/core/app.jswszystko się sprowadza, ponieważ dzięki temu ten post byłby bardzo, bardzo długi, ale podsumowanie jest następujące:

  • Magento_Ui/js/core/app-Component tworzy checkout-component.
  • Będzie to komponent tego typu uiComponent(jest to bardzo ogólny komponent, którego można użyć do odroczenia własnego niestandardowego komponentu interfejsu użytkownika. Jest wyposażony w podstawowe renderowanie szablonów i tym podobne).
  • To nam szablon Magento_Checkout/web/frontend/template/onepage.html.
  • Będzie tworzyć różne dzieci (z nazwą errors, estimation, steps, etc ...)
  • steps-Child będzie również uiComponent.
  • Ten cykl trwa ... konfiguracja sprawia, że ​​dzieci mają różne parametry.

Przejdźmy teraz do pytania displayAreai provider: Pytanie: Jak widzieliśmy powyżej, wszystko odwzorowuje się na klasy JavaScrip. Po raz pierwszy widzimy użycie, displayAreagdy tworzymy steps-komponent, który jest tego typu uiComponent. uiComponentByłby więc logicznym kandydatem do szukania zastosowania displayArea.

A uiComponentto klasa JavaScript tego typu Magento_Ui/js/lib/core/collection. (Możesz to sprawdzić w module-ui/view/base/requirejs-config.js). To odwzorowuje na module-ui/view/base/web/js/lib/core/collection.js. Tutaj widzimy następujące zastosowanie:

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

Więc co to w efekcie powoduje, „mapuje” komponent uiComponent do pewnej grupy komponentów interfejsu użytkownika. Jest to ważne, ponieważ pozwala nam przenosić komponenty interfejsu użytkownika do innych lokalizacji w układzie, po prostu manipulując układem XML, podobnie jak w przypadku phtmlszablonów renderowanych po stronie serwera. Wystarczy zastąpić displayAreai można renderować dowolny komponent interfejsu użytkownika JavaScript gdziekolwiek indziej (biorąc pod uwagę, że obszar docelowy jest również renderowany gdzieś).

Teraz do drugiego pytania: provider. Tak jak spojrzeliśmy w górę displayArea, powinniśmy najpierw zacząć przyglądać się komponentowi interfejsu użytkownika Magento_Checkout/js/view/form/element/email. A jeśli spojrzymy na to requirejs-config.js, w końcu znajdziemy module-checkout/view/frontend/web/js/view/form/element/email.js.

Ale ... nie providerjest używane w tej klasie. Zobaczmy więc, czy możemy znaleźć coś w klasie, którą on rozszerza: Component(która jest uiComponentponownie naszą klasą ).

Ale ... też nie provider. Cóż, uiComponentpo prostu rozszerza Element(który znajduje się w module-ui/view/base/web/js/lib/core/element/element.js), więc spójrzmy tam:

/**
 * 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! Okazuje się, że dostawca jest wykorzystywany jako źródło pobierania danych. Jeśli spojrzymy na konstruktor Element, zobaczysz, że domyślnie jest ustawiony na pusty:

provider: '',

Wróćmy do naszej konfiguracji. Jeśli teraz przeczytamy naszą konfigurację, zrozumiemy, że element shippingAddressjest składnikiem Magento_Checkout/js/view/shipping, który pobiera z niego dane checkoutProvider.

Pozostają nam zatem dwa pytania:

  1. Gdzie jest checkoutProviderzdefiniowane?
  2. Jak jest używany w wysyłce JavaScript?

Cóż, jeśli przewiniesz na dół checkout_index_index.xml, zauważysz, że to nic innego jak wanilia uiComponent:

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

A jeśli spojrzysz module-checkout/view/frontend/web/js/view/shipping.js, zobaczysz, że jest on używany w następujący sposób:

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

Szczerze mówiąc: w tym miejscu kończy się moja analiza, ponieważ trudno mi również wyszukiwać i inwestować w to, co się dzieje, ale mam nadzieję, że ktoś inny może to stąd odebrać ...

Wiem, że ma to coś wspólnego ze registry.async()zwróceniem metody, która jest natychmiast wykonywana z funkcją wywołania zwrotnego jako argumentem, ale ktoś inny musi to wyjaśnić ...


* Uwaga: W każdym razie, proszę mnie poprawić, jeśli się mylę! Naprawdę nie próbowałem żadnego z powyższych, ale prawie od roku pracuję z Magento 2 i wierzę, że tak to działa. Niestety nie ma zbyt wiele dokumentacji, jeśli chcesz nurkować na dnie Oceanu Magento.

Giel Berkers
źródło
2
więc czym jest displayArea?
Marián Zeke Šedaj
1
To jest genialna analiza, czy zdarzyło Ci się kiedykolwiek lepiej zrozumieć?
LM_Fielding
11

6 miesięcy po mojej pierwotnej odpowiedzi myślę, że mogę udzielić lepszej odpowiedzi na to, co displayAreajest.

W moim rozumieniu wszystko to łączy się z getTemplate()metodą Knockouta , getRegion()metodą i dziećmi w komponentach interfejsu użytkownika. Dobry przykład tego można zobaczyć podczas badania vendor/magento/module-checkout/view/frontend/templates/registration.phtmli vendor/magento/module-checkout/view/frontend/web/template/registration.html.

W registration.phtmlzobaczysz domyślny komponent interfejsu użytkownika Magento, który ma dzieci:

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

Zwróć uwagę na użycie displayAreaw children-node. Zasadniczo mówi Knockoutowi, że ten element potomny powinien być renderowany w regionie zwanym „wiadomościami” .

Teraz spójrz na górę registration.html:

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

Co ta linia kodu Knockout zasadzie robi, jest to iteracje nad wszystkich elementów podrzędnych, które są obecne w displayArea „Wiadomości” , i czyni je.

Zasadniczo nazwa jest nieco myląca, jeśli mnie o to poprosisz. Dlaczego miałbyś używać „displayArea” w jednym miejscu, a „region” w innym miejscu. Ale może moje założenie jest całkowicie błędne. Być może twórca rdzenia Magento mógłby rzucić na to nieco więcej światła?

Giel Berkers
źródło
1
To mnie tak długo myliło, ciągle widzę, getRegiona mój umysł po prostu imploduje. Nawiasem mówiąc, dziękuję za obie odpowiedzi, bardzo pomocne!
Ben Crook,
1
Cóż, to tylko moje 2 centy. Mam nadzieję, że ktoś z głównych programistów podzieli się trochę światła na ten temat. Głębsze elementy wewnętrzne Magento 2, a zwłaszcza cała implementacja Knockout / XHR, są czymś, co nie zostało tak dobrze udokumentowane.
Giel Berkers
2
Uzgodnione, chyba że zagłębisz się w wiele podstawowych plików, nie ma innego sposobu niż wymiana stosów, aby dowiedzieć się, co się do cholery dzieje.
Ben Crook,