Magento 2: Sincronizando back-end e estado / cache de front-end

14

O Magento 2 possui sistemas ou abstrações para gerenciar o estado entre o back-end e o armazenamento local no front-end?

Estou trabalhando na portabilidade de um recurso para restaurar o carrinho abandonado de um usuário por meio de um URL de redirecionamento. De forma simplificada, um URL como

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

carregará uma cotação no carrinho do usuário atual com base em um quote_id codificado no identificador.

No Magento 1, isso era relativamente simples - você só precisava atualizar as informações da sessão do Checkout de um usuário com o ID da cotação correto. No entanto, o Magento 2 aumenta as rugas do armazenamento local .

Os aplicativos javascript front-end do Magento 2 parecem armazenar informações em cache nos bancos de dados de armazenamento local do navegador. Isso inclui informações para a construção do minicarrinho. O que isso significa é que, mesmo que um programador de usuário final (eu) consiga alterar a ID da sessão da sessão no back-end, o minicarro ainda exibirá os dados antigos do carrinho.

Este é apenas um exemplo de um problema que decorre de não conhecer (ou ter?) Uma única API para gerenciar o estado do aplicativo no back-end e no front-end. Para o meu problema específico, meu ponto de extremidade processou uma página HTML que inclui algum javascript. Ele limpa manualmente o armazenamento local e depois redireciona o usuário para outra página - mas isso parece um hack total.

Existe uma API no Magento 2 para gerenciar dados entre o front-end e o back-end?

Existe uma maneira padrão de sinalizar todo o sistema que, durante o processamento de back-end, você fez algo que torna necessário invalidar o cache de armazenamento local de front-end?

Existe uma técnica para injetar um novo módulo RequireJS na página que é executada automaticamente e pode manipular o armazenamento local antes que o restante do (s) aplicativo (s) javascript os acesse?

Alan Storm
fonte
Ei. Caro Alan Store, você conseguiu resposta?
Amit Bera
@AmitBera Ainda não.
Alan Storm

Respostas:

6

Eu tive um problema semelhante: queria que o componente do minicarrinho fosse atualizado depois de enviar uma solicitação do Ajax para adicionar um item ao carrinho.

Na verdade, funciona muito bem se você se lembrar de alguns pontos:

  • Declare quais seções da página precisam ser atualizadas após uma chamada do Ajax, em etc / frontend / seções.xml do seu módulo.
  • Use jQuery.post () para enviar sua solicitação de Ajax. Pode ser uma solicitação POST ou PUT, mas não GET.
  • E deve ser através do jQuery, não do Prototype ou do vanilla JS, porque é o evento 'ajaxComplete' do jQuery que desempenha um papel essencial.
  • preceda o URL do Ajax com um URL base (não basta começar com /)

Aqui está o meu section.xml (xyz é o nome do nosso cliente):

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

Aqui, 'xyz-ajax / cart / add' está de acordo com o formato '[frontName] / [ActionPath] / [ActionName]'. O xml diz ao Magento para atualizar o 'carrinho' após a chamada do ajax "xyz-ajax / cart / add" ser concluída.

Este é o código do meu modelo (.phtml):

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

e este é o código JS que envia a solicitação do Ajax:

função requestComplete (responseData) {}

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

O que acontece no processo?

Toda vez que seu script envia uma solicitação Ajax POST (ou PUT) ao servidor via jQuery e retorna, o jQuery envia um evento 'ajaxComplete'. Este evento é tratado por um manipulador em module-customer / view / frontend / web / js / customer-data.js. Esse manipulador verifica quais seções da página dependem da chamada do Ajax (do seu section.xml) e as invalida. Estes serão atualizados.

Fontes:

Patrick van Bergen
fonte
14

O Magento 2 usa a API JS de dados do cliente para representar os dados da sessão do usuário no navegador. Todos os widgets JS devem recuperar dados do cliente da API JS de dados do cliente. Os dados do cliente são divididos em seções (carrinho, lista de desejos, ...). Cada segmento é observável; portanto, sempre que é modificado, o widget que o utiliza é renderizado novamente para exibir a alteração.

A estrutura Magento é responsável pela sincronização da sessão PHP e do armazenamento local JS Dados do Cliente.

Sempre que um visitante com cookie de ID de sessão e armazenamento local vazio visita a página Magento, é feita uma solicitação HTTP ao servidor para recuperar os dados do cliente (todas as seções).

Sempre que o visitante realiza alguma operação de modificação do estado (adicionar ao carrinho, adicionar aos desejos), a seção correspondente dos dados do cliente é invalidada no armazenamento local e outra solicitação HTTP é feita para recuperar as seções atualizadas.

Você pode usar 'seções.xml' para vincular ações POST a seções de armazenamento local que serão invalidadas sempre que essas ações forem chamadas. Veja https://github.com/magento/magento2/blob/develop/app/code/Magento/Checkout/etc/frontend/sections.xml, por exemplo.

Anton Kril
fonte
2

Com base nessas outras respostas, se você estiver atualizando o carrinho por meio de chamadas de API em require.jsarquivos Magento normais , mas não puder confiar no ajaxCompletemétodo jQuery para atualizar o minicart (usando outra estrutura de solicitação AJAX?), Poderá solicitar o Magento_Customer/js/customer-dataobjeto e perguntar o minicart para atualizar dessa maneira também:

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

Fonte: https://github.com/magento/magento2/issues/5621

thaddeusmt
fonte