що означає "displayArea" та "провайдер" checkout_index_index.xml в magento2


Відповіді:


22

Для того, щоб зрозуміти , що checkoutProviderі displayAreaє, ви повинні спочатку зрозуміти область , яку ви шукаєте в: jsLayout.

jsLayoutце купа конфігурації JavaScript для елементів інтерфейсу JavaScript на сторінці оформлення замовлення. Якщо ви подивитесь module-checkout/view/frontend/templates/onepage.phtml, ви помітите наступні x-magento-initдані:

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

Тут все починається. У ньому зазначено:

Для елемента #checkoutініціалізуйте Magento_Ui/js/core/app-компонент із такою інформацією: ...

А інформація , яку вона отримує це інформація , створена в макеті XML: jsLayout. Це означає, що все у вашому XML зараз передається до Magento_Ui/js/core/app-компонента (залишаючи плагіни та процесори компонування та інше з рівняння на даний момент ...)

Зараз я не збираюся заглиблюватися в деталі, як module-ui/view/base/web/js/core/app.jsвсе зводить, бо це зробило б цю публікацію дуже-дуже довгою, але резюме таке:

  • Magento_Ui/js/core/appКомпонентний створює checkout-компонент.
  • Це буде компонент цього типу uiComponent(це дуже загальний компонент, який можна використовувати для відстрочення власних користувальницьких компонентів інтерфейсу. Поставляється з базовим візуалізацією шаблонів вибивання та ін.).
  • Це буде нам шаблон Magento_Checkout/web/frontend/template/onepage.html.
  • Він буде створювати різні дитина (з ім'ям errors, estimation, stepsі т.д. ...)
  • steps-Child буде також uiComponent.
  • Цей цикл продовжується ... конфігурація робить дітей з різними параметрами.

Тепер , щоб дістатися до displayAreaі provider-question: Як ви вже бачили вище, всі карти на класи JavaScrip. Перший раз, коли ми бачимо використання, displayAreaце коли ми створюємо steps-компонент, який має тип uiComponent. Тож uiComponentбуло б логічним кандидатом шукати використання displayArea.

Тепер uiComponentклас класу JavaScript Magento_Ui/js/lib/core/collection. (Ви можете подивитися це вгорі module-ui/view/base/requirejs-config.js). Це карти для module-ui/view/base/web/js/lib/core/collection.js. Тут ми бачимо наступне використання:

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

Отже, що це робить насправді, воно "відображає" uiComponent на певну групу компонентів інтерфейсу. Це важливо знати, оскільки це дозволяє нам переміщувати компоненти інтерфейсу користувача в інші місця в макеті, просто маніпулюючи компонуванням XML так, як ви це робите з phtmlшаблонами, які надаються на стороні сервера. Просто замініть displayArea, і ви можете візуалізувати будь-який компонент інтерфейсу JavaScript у будь-якому іншому місці (враховуючи, що цільова область також десь надана).

Тепер для вашого другого запитання: provider. Так само, як ми подивилися вгору displayArea, ми повинні почати спочатку переглядати компонент інтерфейсу, який є Magento_Checkout/js/view/form/element/email. І якщо ми подивимось на requirejs-config.js, ми нарешті знайдемо module-checkout/view/frontend/web/js/view/form/element/email.js.

Але ... ні providerв цьому класі не використовується. Тож давайте просто подивимось, чи зможемо ми знайти що-небудь у класі, який він розширює: Component(який uiComponentзнову - наш клас).

Але ... також не providerтак. Ну uiComponentпросто розширюється Element(що знаходиться на module-ui/view/base/web/js/lib/core/element/element.js), так що давайте просто подивимось там:

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

Бінго! Виявляється, провайдер використовується як джерело для отримання даних з. Якщо ми подивимось на конструктор Element, ви побачите, що за замовчуванням воно встановлено порожнім:

provider: '',

Тож повернемося до нашої конфігурації. Якщо ми зараз прочитаємо нашу конфігурацію, то зрозуміємо, що елемент shippingAddressє компонентом Magento_Checkout/js/view/shipping, що отримує його дані з checkoutProvider.

Отже, ми залишаємо два питання:

  1. Де checkoutProviderвизначено?
  2. Як це використовується в JavaScript для доставки?

Що ж, якщо ви прокрутите донизу checkout_index_index.xml, ви помітите, що це не що інше, як ваніль uiComponent:

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

А якщо ви подивитесь module-checkout/view/frontend/web/js/view/shipping.js, то побачите, що він використовується так:

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

Якщо чесно: на цьому мій аналіз зупиняється, тому що мені також важко шукати та інвестувати те, що відбувається, але я сподіваюся, що хтось ще може взяти це звідси ...

Я знаю, що це має щось registry.async()спільне з методом повернення, який негайно виконується з функцією зворотного виклику як аргумент, але комусь іншому потрібно пояснити це ...


* Відмова: У будь-якому випадку, будь ласка, виправте мене, якщо я помиляюся! Я не пробував реально описаного вище, але я майже рік працюю з Magento 2, і я вважаю, що це працює. На жаль, не так багато документації, якщо ви хочете пірнути на дно океану Магенто.


2
так що таке displayArea?
Marián Zeke Šedaj

1
Це геніальний аналіз, чи ви коли-небудь розвивали подальше розуміння?
LM_Fielding

11

Через 6 місяців після моєї первинної відповіді я думаю, що можу дати кращу відповідь на те, що displayAreaє.

На моє розуміння, все це поєднується з -методом Knockouts getTemplate(), getRegion()-методом та дітьми в компонентах інтерфейсу користувача. Хороший приклад цього можна побачити при обстеженні vendor/magento/module-checkout/view/frontend/templates/registration.phtmlта vendor/magento/module-checkout/view/frontend/web/template/registration.html.

У ньому registration.phtmlви побачите компонент інтерфейсу Magento UI, який має дітей:

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

Зверніть увагу на використання displayAreaу children-ноді. В основному, це говорить нокауту, що цей дочірній елемент повинен бути відображений у регіоні, який називається "повідомлення" .

Тепер подивіться на верхню частину registration.html:

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

Що в основному робить цей рядок коду Knockout, це: він повторює всі дочірні елементи, які є у "повідомленнях" displayArea , і відображає їх.

В основному, називання трохи заплутане, якщо ви запитаєте мене. Чому б ви використовували "displayArea" в одному місці, а "region" в іншому. Але, можливо, моє припущення є абсолютно невірним. Можливо, розробник Magento core міг би просвітити на цьому трохи більше світла?


1
Це те, що мене так довго бентежить, я продовжую бачити, getRegionа мій розум просто розгортається. Дякую за обидві відповіді, до речі, дуже корисно!
Бен Крук

1
Ну, це лише мої 2 копійки. Я сподіваюся, що хтось із основних розробників може поділитися світлом на цю тему. Більш глибока внутрішність Magento 2, і особливо вся реалізація Knockout / XHR - це щось не так добре зафіксовано.
Гіель Беркерс

2
Домовились, якщо ви не заглибитесь у багато основних файлів, майже нічого іншого, крім цього обміну стеками, немає, щоб дізнатися, що, до біса.
Бен Крук
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.