Magento 2: Синхронизация внутреннего и внешнего состояния/кэша


Есть ли в Magento 2 какие-либо системы или абстракции для управления состоянием между серверной частью и локальным хранилищем на интерфейсе?

Я работаю над переносом функции для восстановления заброшенной корзины пользователя с помощью URL-адреса перенаправления. В упрощенной форме URL-адрес, такой как

http://magento.example.com/restore/the/cart?identifier=sdkfjh48v237g5

Загрузит предложение в корзину текущего пользователя на основе закодированного идентификатора quote_id в идентификаторе.

В Magento 1 это было относительно просто - вам просто нужно было обновить пользовательский Информация о сеансе проверки с правильным идентификатором предложения. Однако Magento 2 добавляет в складку локальное хранилище .

Интерфейсное приложение javascript Magento 2 (ы?), Похоже, кэширует информацию в локальных базах данных браузера. Это включает в себя информацию для создания мини-тележки. Это означает, что даже если программисту - конечному пользователю (мне) удастся изменить идентификатор сеанса сеанса в бэкэнде, мини-корзина все равно будет отображать старые данные корзины.

Это всего лишь один пример проблемы, которая возникает из-за незнания (или наличия?) единый API для управления состоянием приложений в бэкэнде и интерфейсе. Для моей конкретной проблемы у меня была конечная точка, отображающая HTML-страницу, которая включает в себя некоторый javascript, вручную очищает локальное хранилище, а затем перенаправляет пользователя на другую страницу - но это похоже на грубый взлом.

Есть ли в Magento 2 API для управления данными между интерфейсом и серверной частью?

Там а стандартный способ сигнализации всей системе о том, что во время серверной обработки вы сделали что-то, что делает необходимым аннулировать кэш локального хранилища внешнего интерфейса?

Существует ли способ внедрения нового модуля RequireJS на страницу, который запускается автоматически и может управлять локальным хранилищем до того, как к нему обратится остальная часть приложения(приложений) javascript?

Author: Alan Storm, 2015-12-10

3 answers

У меня была аналогичная проблема: я хотел, чтобы компонент мини-корзины обновился после того, как я отправил запрос Ajax на добавление товара в корзину.

На самом деле это работает довольно хорошо, если вы просто запомните некоторые моменты:

  • Объявите, какие разделы страницы необходимо обновить после вызова Ajax, в etc/frontend/sections.xml вашего модуля.
  • Используйте jQuery.post() для отправки вашего запроса Ajax. Это может быть сообщение или запрос на отправку, просто не ПОЛУЧИТЬ.
  • И это должно быть через jQuery, а не Прототип или ванильный JS, потому что именно событие jQuery "ajaxComplete" играет важную роль.
  • добавьте к URL-адресу Ajax базовый URL-адрес (не начинайте просто с /)

Вот мой sections.xml (xyz - это имя нашего клиента):

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="xyz-ajax/cart/add">
        <section name="cart"/>
    </action>
</config>

Здесь "xyz-ajax/корзина/добавить" соответствует формату "[Имя пользователя]/[Путь действия]/[Имя действия]". xml указывает Magento обновить "корзину" после завершения вызова ajax "xyz-ajax/корзина/добавить".

Это мой шаблон (.phtml) код:

<script type="text/javascript">
    require(['jquery', 'BigBridge_XYZ/option_selector'], function($, optionSelect) {
        optionSelect.create(<?= json_encode($componentData) ?>, $);
    })
</script>

И это код JS, который отправляет запрос Ajax:

Функция requestComplete(данные ответа){ }

$.post(baseUrl + 'xyz-ajax/cart/add/cf/' + configurableProductId + '/simple/' + item.simpleProductId + '/amount/' + item.amount, requestComplete);

Что происходит в процессе?

Каждый раз, когда ваш скрипт отправляет запрос Ajax POST (или PUT) на сервер через jQuery, и он возвращается, jQuery отправляет событие "ajaxComplete". Это событие обрабатывается обработчиком в module-customer/view/frontend/web/js/customer-data.js . Этот обработчик проверяет, какие разделы страницы зависят от вызова Ajax (от вашего sections.xml) и делает их недействительными. Они будут обновлены.

Источники:

 6
Author: Patrick van Bergen, 2017-04-13 12:55:02

Magento 2 использует JS API клиентских данных для представления данных сеанса пользователя в браузере. Все виджеты JS должны извлекать данные клиентов из API JS данных клиентов. Данные о клиентах разбиты на разделы (корзина, список пожеланий,...). Каждый сегмент доступен для наблюдения, поэтому всякий раз, когда он изменяется, виджет, который его использует, повторно отображается для отображения изменений.

Платформа Magento отвечает за синхронизацию сеанса PHP и данных клиента локального хранилища JS.

Каждый раз, когда посетитель с помощью файла cookie идентификатора сеанса и пустого локального хранилища посещается страница Magento, выполняется HTTP-запрос на сервер для получения данных клиента (все разделы).

Каждый раз, когда посетитель выполняет какую-либо операцию по изменению состояния (добавить в корзину, добавить в список желаний), соответствующий раздел данных клиента становится недействительным в локальном хранилище и выполняется другой HTTP-запрос для получения обновленных разделов.

Вы можете использовать'sections.xml "чтобы связать действия по публикации с разделами локального хранилища, которые будут признаны недействительными всякий раз, когда вызываются эти действия. Видишь https://github.com/magento/magento2/blob/develop/app/code/Magento/Checkout/etc/frontend/sections.xml например.

 14
Author: Anton Kril, 2016-01-07 15:14:38

Основываясь на этих других ответах, если вы обновляете корзину с помощью вызовов API в обычных файлах Magento require.js, но вы не можете полагаться на метод jQuery ajaxComplete для обновления мини-карты (используя другую структуру запросов AJAX?), вы можете потребовать объект Magento_Customer/js/customer-data и попросить мини-карту также обновить таким образом:

<script>
    require([
        'Magento_Customer/js/customer-data'
    ], function (customerData) {
        var sections = ['cart'];
        customerData.invalidate(sections);
        customerData.reload(sections, true);
    });
</script>

Источник: https://github.com/magento/magento2/issues/5621

 2
Author: thaddeusmt, 2017-06-14 17:27:16