Что именно эти разделы?
Раздел - это часть данных клиента, сгруппированных вместе. Каждый раздел представлен ключом, который используется для доступа и управления данными и самими данными. Magento загружает разделы по запросу AJAX /customer/section/load/
и кэширует загруженные данные в локальном хранилище браузера под ключом mage-cache-storage
. Magento отслеживает изменение какого-либо раздела и автоматически загружает обновленный раздел.
Как вы определяете раздел?
Раздел, определенный в di.xml
файле путем добавления нового раздела в пул разделов
<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>
Таким образом , здесь два новых раздела регистрируются cart
и directory-data
. Magento\Checkout\CustomerData\Cart
и Magento\Checkout\CustomerData\DirectoryData
реализует Magento\Customer\CustomerData\SectionSourceInterface
и предоставляет фактические данные как результат getSectionData
метода.
Как запускаются обновления раздела?
Magento предполагает , что личные данные клиента изменяется , когда клиент отправляет запрос на некоторое состояние модификации ( POST
, PUT
, DELETE
). Чтобы свести к минимуму нагрузку на сервер, разработчики должны указать, какое действие (или запрос) обновляет какой раздел данных клиента etc/section.xml
.
<action name="checkout/cart/add">
<section name="cart"/>
</action>
Имя действия - это шаблон ключа действия. Когда пользователь вызывает действие, соответствующее указанному шаблону, Magento обнаружит, что соответствующий раздел устарел, и снова загрузит его. Если имя действия *
означает, что раздел будет обновляться при каждом запросе POST и PUT. Если тег раздела пропущен, то весь раздел будет обновлен.
Поэтому концептуально неправильно обновлять мини-корзину, когда вы загружаете страницу корзины. На этом этапе мини-корзина (или раздел корзины) уже должна быть обновлена.
Вы можете найти больше информации о данных клиента здесь
Внутренняя реализация
Чтобы понять, когда и как обновляются разделы, посмотрим реализацию. Ключом к пониманию являются файлы magento2ce/app/code/Magento/Customer/view/frontend/web/js/section-config.js
и magento2ce/app/code/Magento/Customer/view/frontend/web/js/customer-data.js
.
В конце последнего один из двух обработчиков событий регистрируется для ajaxComplete
и submit
. Это означает , что , когда любая форма размещена (с POST или методов PUT) к серверу, или когда JavaScript посылает AJAX
, POST
или PUT
запрос, обработчики будут вызываться. Оба обработчика имеют схожую логику: с помощью Magento_Customer/js/section-config
проверки должен обновляться любой раздел или нет. Если какой-то раздел должен быть обновлен, то customerData.invalidate(sections)
называется. И позже все недействительные разделы загружаются с сервера.
Итак, как Magento_Customer/js/section-config
узнать, какой раздел должен быть удален и какое действие? Ответ в 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>
Таким образом, сервер передает конфигурацию объединенных секций в браузер.
Таким образом, при условии всего этого, раздел может быть обновлен только путем отправки формы POST или PUT или запроса AJAX.
Кроме того, есть только две заметки:
- все, что здесь описано, является внутренней реализацией и может быть изменено, так что вы можете безопасно использовать только section.xml и ожидать обновления раздела, когда инициируются указанные действия POST или PUT или DELETE.
- если вы уверены, что вам действительно нужно обновить какой-то раздел, вы всегда можете сделать что-то вроде этого:
require('Magento_Customer/js/customer-data').reload(['cart'], false)