Magento 2: sincronizzazione di backend e stato / cache del frontend


14

Magento 2 ha dei sistemi o astrazioni per la gestione dello stato tra il back-end e l'archiviazione locale sul front-end?

Sto lavorando al porting di una funzione per ripristinare il carrello abbandonato di un utente tramite un URL di reindirizzamento. In forma semplificata, un URL come

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

caricherà un preventivo nel carrello dell'utente corrente sulla base di un quote_id codificato nell'identificatore.

In Magento 1, questo era relativamente semplice: era sufficiente aggiornare le informazioni sulla sessione di checkout di un utente con l'ID preventivo corretto. Tuttavia, Magento 2 aggiunge la piega della memoria locale .

Le applicazioni javascript frontend Magento 2 sembrano memorizzare nella cache le informazioni nei database di archiviazione locale del browser. Ciò include le informazioni per la costruzione del mini-carrello. Ciò significa che anche se un programmatore dell'utente finale (me) riesce a modificare l'ID sessione della sessione nel back-end, il mini-carrello visualizzerà comunque i vecchi dati del carrello.

Questo è solo un esempio di un problema che deriva dal non conoscere (o avere?) Una singola API per gestire lo stato dell'applicazione attraverso il backend e il frontend. Per il mio problema specifico ho avuto il mio endpoint nel rendering di una pagina HTML che include alcuni javascript che cancella manualmente l'archiviazione locale e quindi reindirizza l'utente a un'altra pagina, ma questo sembra un vero e proprio hack.

Esiste un'API in Magento 2 per la gestione dei dati tra frontend e backend?

Esiste un modo standard per segnalare all'intero sistema che, durante l'elaborazione del back-end, hai fatto qualcosa che lo rende necessario invalidando la cache di archiviazione locale del front-end?

Esiste una tecnica per iniettare un nuovo modulo RequireJS nella pagina che viene eseguita automaticamente e può manipolare l'archiviazione locale prima che il resto delle applicazioni javascript acceda ad esso?


Hey. Caro Alan Store, hai ricevuto risposta?
Amit Bera

@AmitBera Non ancora.
Alan Storm,

Risposte:


6

Ho avuto un problema simile: volevo che il componente mini-carrello si aggiornasse dopo aver inviato una richiesta Ajax per aggiungere un articolo al carrello.

In realtà funziona abbastanza bene se ricordi solo alcuni punti:

  • Dichiara quali sezioni di pagina devono essere aggiornate dopo una chiamata Ajax, in etc / frontend / sezioni.xml del modulo.
  • Usa jQuery.post () per inviare la tua richiesta Ajax. Potrebbe essere una richiesta POST o PUT, ma non OTTENERE.
  • E deve essere tramite jQuery, non Prototype o Vanilla JS, perché è l'evento 'ajaxComplete' di jQuery che svolge un ruolo essenziale.
  • anteporre l'URL Ajax con un url base (non iniziare solo con /)

Ecco il mio sezioni.xml (xyz è il nome del nostro 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>

Qui, "xyz-ajax / cart / add" è conforme al formato "[frontName] / [ActionPath] / [ActionName]". L'xml dice a Magento di aggiornare 'cart' dopo che la chiamata ajax "xyz-ajax / cart / add" è stata completata.

Questo è il mio codice template (.phtml):

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

e questo è il codice JS che invia la richiesta Ajax:

function requestComplete (responseData) {}

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

Cosa succede nel processo?

Ogni volta che lo script invia una richiesta POST (o PUT) Ajax al server tramite jQuery e viene restituito, jQuery invia un evento 'ajaxComplete'. Questo evento è gestito da un gestore in module-customer / view / frontend / web / js / customer-data.js. Questo gestore controlla quali sezioni di pagina dipendono dalla chiamata Ajax (dal vostro sezioni.xml) e le invalida. Questi saranno aggiornati.

fonti:


14

Magento 2 utilizza l'API JS dei dati cliente per rappresentare i dati della sessione utente nel browser. Tutti i widget JS dovrebbero recuperare i dati dei clienti dall'API JS dei dati dei clienti. I dati del cliente sono suddivisi in sezioni (carrello, lista dei desideri, ...). Ogni segmento è osservabile, quindi ogni volta che viene modificato, il widget che lo utilizza viene nuovamente renderizzato per visualizzare la modifica.

Il framework Magento è responsabile della sincronizzazione della sessione PHP e dei dati del cliente di archiviazione locale JS.

Ogni volta che un visitatore con cookie ID sessione e memoria locale vuota visita la pagina Magento, viene effettuata una richiesta HTTP al server per recuperare i dati dei clienti (tutte le sezioni).

Ogni volta che il visitatore esegue un'operazione di modifica dello stato (aggiungi al carrello, aggiungi a wishlit), la sezione corrispondente dei dati del cliente viene invalidata nella memoria locale e viene fatta un'altra richiesta HTTP per recuperare sezioni aggiornate.

È possibile utilizzare 'sezioni.xml' per collegare le azioni POST alle sezioni di archiviazione locali che verranno invalidate ogni volta che vengono chiamate tali azioni. Vedi https://github.com/magento/magento2/blob/develop/app/code/Magento/Checkout/etc/frontend/sections.xml per esempio.


2

Basandoti su queste altre risposte, se stai aggiornando il carrello tramite chiamate API in normali require.jsfile Magento , ma non puoi fare affidamento sul ajaxCompletemetodo jQuery per aggiornare la minicart (usando un altro framework di richieste AJAX?), Puoi richiedere l' Magento_Customer/js/customer-dataoggetto e chiedere la minicart per aggiornare anche in questo modo:

<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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.