Czym dokładnie są te sekcje?
Sekcja to zgrupowane dane klienta. Każda sekcja jest reprezentowana przez klucz, który służy do uzyskiwania dostępu do danych i zarządzania nimi. Magento ładuje sekcje według żądania AJAX /customer/section/load/
i buforuje załadowane dane w lokalnej pamięci przeglądarki pod kluczem mage-cache-storage
. Magento śledzi zmiany niektórych sekcji i automatycznie ładuje zaktualizowane sekcje.
Jak definiujesz sekcję?
Sekcja zdefiniowana w di.xml
pliku przez dodanie nowej sekcji do puli sekcji
<type name="Magento\Customer\CustomerData\SectionPoolInterface">
<arguments>
<argument name="sectionSourceMap" xsi:type="array">
<item name="cart" xsi:type="string">Magento\Checkout\CustomerData\Cart</item>
<item name="directory-data" xsi:type="string">Magento\Checkout\CustomerData\DirectoryData</item>
</argument>
</arguments>
</type>
Więc tutaj zarejestrowane są dwie nowe sekcje cart
i directory-data
. Magento\Checkout\CustomerData\Cart
oraz Magento\Checkout\CustomerData\DirectoryData
wdraża Magento\Customer\CustomerData\SectionSourceInterface
i dostarcza rzeczywiste dane w wyniku getSectionData
metody.
W jaki sposób uruchamiane są aktualizacje sekcji?
Magento zakłada, że prywatne dane klienta ulega zmianie, gdy klient wysyła żądanie modyfikacji jakiś stan ( POST
, PUT
, DELETE
). Aby zminimalizować obciążenie serwera, programiści powinni określić, które działanie (lub żądanie) aktualizuje sekcję danych klienta etc/section.xml
.
<action name="checkout/cart/add">
<section name="cart"/>
</action>
Nazwa akcji to wzór klucza akcji. Gdy użytkownik wezwie do działania pasującego do określonego wzorca, Magento wykryje, że odpowiednia sekcja jest nieaktualna i załaduje ją ponownie. Jeśli nazwa akcji to *
oznacza, że sekcja będzie aktualizowana przy każdym żądaniu POST i PUT. Jeśli tag sekcji zostanie pominięty, wszystkie sekcje zostaną zaktualizowane.
Więc koncepcyjnie źle jest aktualizować mini koszyk, gdy strona z bogatym koszykiem jest. W tym momencie mini koszyk (lub sekcja koszyka) powinien już zostać zaktualizowany.
Więcej informacji o danych klientów można znaleźć tutaj
Wdrożenie wewnętrzne
Aby zrozumieć, kiedy i jak sekcje są aktualizowane, zobaczmy implementację. Kluczem do zrozumienia są pliki magento2ce/app/code/Magento/Customer/view/frontend/web/js/section-config.js
i magento2ce/app/code/Magento/Customer/view/frontend/web/js/customer-data.js
.
Na koniec ostatniego z dwóch zarejestrowanych programów obsługi zdarzeń dla ajaxComplete
i submit
. Oznacza to, że gdy każda forma jest zamieszczona (z metody POST lub PUT) do serwera lub gdy JavaScript wysyła AJAX
, POST
lub PUT
wniosek, koparki zostanie wywołany. Oba programy obsługi mają podobną logikę: przy pomocy Magento_Customer/js/section-config
sprawdzania należy zaktualizować dowolną sekcję. Jeśli jakaś sekcja powinna zostać zaktualizowana, wówczas customerData.invalidate(sections)
jest wywoływana. A później wszystkie unieważnione sekcje są ładowane z serwera.
Magento_Customer/js/section-config
Skąd więc wiadomo, którą sekcję należy usunąć i na której akcji? Odpowiedź jest w Magento/Customer/view/frontend/templates/js/section-config.phtml
:
<script type="text/x-magento-init">
<?php
/* @noEscape */ echo $this->helper(\Magento\Framework\Json\Helper\Data::class)->jsonEncode([
'*' => ['Magento_Customer/js/section-config' => [
'sections' => $block->getSections(),
'clientSideSections' => $block->getClientSideSections(),
'baseUrls' => array_unique([
$block->getUrl(null, ['_secure' => true]),
$block->getUrl(null, ['_secure' => false]),
]),
]],
]);
?>
</script>
W ten sposób serwer przekazuje konfigurację scalonych sekcji do przeglądarki.
Zakładając, że wszystko to, sekcja może być aktualizowana tylko przez przesłanie formularza POST lub PUT lub żądanie AJAX
Ponadto istnieją tylko dwie notatki:
- wszystko tutaj opisane jest implementacją wewnętrzną i może być zmienione, więc możesz bezpiecznie używać tylko section.xml i oczekiwać aktualizacji sekcji, gdy zostaną uruchomione określone działania POST lub PUT lub DELETE.
- jeśli jesteś pewien, że naprawdę potrzebujesz zaktualizować jakąś sekcję, zawsze możesz zrobić coś takiego:
require('Magento_Customer/js/customer-data').reload(['cart'], false)