Aby zrozumieć, co checkoutProvider
i displayArea
są, trzeba najpierw zrozumieć zakres szukasz w: jsLayout
.
jsLayout
to 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-init
dane:
<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
#checkout
zainicjujMagento_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.js
wszystko 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.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).Magento_Checkout/web/frontend/template/onepage.html
.errors
, estimation
, steps
, etc ...)steps
-Child będzie również uiComponent
.Przejdźmy teraz do pytania displayArea
i provider
: Pytanie: Jak widzieliśmy powyżej, wszystko odwzorowuje się na klasy JavaScrip. Po raz pierwszy widzimy użycie, displayArea
gdy tworzymy steps
-komponent, który jest tego typu uiComponent
. uiComponent
Byłby więc logicznym kandydatem do szukania zastosowania displayArea
.
A uiComponent
to 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 phtml
szablonów renderowanych po stronie serwera. Wystarczy zastąpić displayArea
i 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 provider
jest używane w tej klasie. Zobaczmy więc, czy możemy znaleźć coś w klasie, którą on rozszerza: Component
(która jest uiComponent
ponownie naszą klasą ).
Ale ... też nie provider
. Cóż, uiComponent
po 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 shippingAddress
jest składnikiem Magento_Checkout/js/view/shipping
, który pobiera z niego dane checkoutProvider
.
Pozostają nam zatem dwa pytania:
checkoutProvider
zdefiniowane?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.
6 miesięcy po mojej pierwotnej odpowiedzi myślę, że mogę udzielić lepszej odpowiedzi na to, co
displayArea
jest.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 badaniavendor/magento/module-checkout/view/frontend/templates/registration.phtml
ivendor/magento/module-checkout/view/frontend/web/template/registration.html
.W
registration.phtml
zobaczysz domyślny komponent interfejsu użytkownika Magento, który ma dzieci:Zwróć uwagę na użycie
displayArea
wchildren
-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
: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?
źródło
getRegion
a mój umysł po prostu imploduje. Nawiasem mówiąc, dziękuję za obie odpowiedzi, bardzo pomocne!