Magento 2: Synchronisation du backend et de l'état / cache du frontend


14

Magento 2 dispose-t-il de systèmes ou d'abstractions pour gérer l'état entre le backend et le stockage local sur le frontend?

Je travaille sur le portage d'une fonctionnalité pour restaurer le panier abandonné d'un utilisateur via une URL de redirection. Sous une forme simplifiée, une URL comme

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

chargera un devis dans le panier de l'utilisateur actuel en fonction d'un quote_id codé dans l'identifiant.

Dans Magento 1, c'était relativement simple - il vous suffisait de mettre à jour les informations de session de paiement d'un utilisateur avec l'ID de devis correct. Cependant, Magento 2 ajoute la ride du stockage local .

La ou les applications javascript frontend de Magento 2 semblent mettre en cache les informations dans les bases de données de stockage local du navigateur. Cela inclut des informations pour la construction du mini-chariot. Cela signifie que même si un utilisateur-programmeur (moi) parvient à modifier l'ID de session de session dans le backend, le mini-chariot affichera toujours les anciennes données du panier.

Ce n'est qu'un exemple d'un problème qui provient du fait de ne pas connaître (ou de ne pas avoir?) Une seule API pour gérer l'état de l'application à travers le backend et le frontend. Pour mon problème spécifique, mon point de terminaison a rendu une page HTML qui inclut du javascript qui efface manuellement le stockage local, puis redirige l'utilisateur vers une autre page - mais cela ressemble à un hack grossier.

Existe-t-il une API dans Magento 2 pour gérer les données entre le frontend et le backend?

Existe-t-il un moyen standard de signaler à l'ensemble du système que, pendant le traitement backend, vous avez fait quelque chose qui rend nécessaire l'invalidation du cache de stockage local frontal?

Existe-t-il une technique pour injecter un nouveau module RequireJS dans la page qui s'exécute automatiquement et peut manipuler le stockage local avant que le reste des applications javascript n'y accèdent?


Hey. Cher Alan Store, avez-vous obtenu une réponse?
Amit Bera

@AmitBera Pas encore.
Alan Storm

Réponses:


6

J'ai eu un problème similaire: je voulais que le composant du mini-panier soit actualisé après avoir envoyé une demande Ajax pour ajouter un article au panier.

Cela fonctionne très bien si vous vous souvenez de certains points:

  • Déclarez quelles sections de page doivent être mises à jour après un appel Ajax, dans etc / frontend / sections.xml de votre module.
  • Utilisez jQuery.post () pour envoyer votre demande Ajax. Il peut s'agir d'une demande POST ou PUT, mais pas GET.
  • Et ce doit être via jQuery, pas Prototype ou vanilla JS, car c'est l'événement 'ajaxComplete' de jQuery qui joue un rôle essentiel.
  • ajouter l'url Ajax avec une URL de base (ne commencez pas simplement par /)

Voici mes sections.xml (xyz est le nom de notre client):

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

Ici, «xyz-ajax / cart / add» est au format «[frontName] / [ActionPath] / [ActionName]». Le xml demande à Magento de mettre à jour 'cart' une fois l'appel ajax "xyz-ajax / cart / add" terminé.

Voici mon code de modèle (.phtml):

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

et voici le code JS qui envoie la requête Ajax:

function requestComplete (responseData) {}

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

Que se passe-t-il dans le processus?

Chaque fois que votre script envoie une requête Ajax POST (ou PUT) au serveur via jQuery, et qu'il revient, jQuery envoie un événement 'ajaxComplete'. Cet événement est géré par un gestionnaire dans module-customer / view / frontend / web / js / customer-data.js. Ce gestionnaire vérifie quelles pages-sections dépendent de l'appel Ajax (à partir de votre sections.xml) et les invalide. Ceux-ci seront mis à jour.

Sources:


14

Magento 2 utilise l'API JS des données client pour représenter les données de session utilisateur dans le navigateur. Tous les widgets JS sont censés récupérer les données client à partir de l'API JS Customer Data. Les données client sont divisées en sections (panier, liste de souhaits, ...). Chaque segment est observable, donc chaque fois qu'il est modifié, le widget qui l'utilise est restitué pour afficher le changement.

Le framework Magento est responsable de la synchronisation des données client de session PHP et de stockage local JS.

Chaque fois qu'un visiteur avec un cookie d'ID de session et un espace de stockage local vide visite la page Magento, une demande HTTP au serveur est effectuée pour récupérer les données client (toutes les sections).

Chaque fois que le visiteur effectue une opération de modification d'état (ajouter au panier, ajouter à wishlit), la section correspondante des données client est invalidée dans le stockage local et une autre requête HTTP est effectuée pour récupérer les sections mises à jour.

Vous pouvez utiliser 'sections.xml' pour lier les actions POST aux sections de stockage local qui seront invalidées chaque fois que ces actions seront appelées. Voir https://github.com/magento/magento2/blob/develop/app/code/Magento/Checkout/etc/frontend/sections.xml par exemple.


2

En vous basant sur ces autres réponses, si vous mettez à jour le panier via des appels d'API dans des require.jsfichiers Magento normaux , mais que vous ne pouvez pas vous fier à la ajaxCompleteméthode jQuery pour actualiser le minicart (en utilisant un autre cadre de demande AJAX?), Vous pouvez exiger l' Magento_Customer/js/customer-dataobjet et demander le minicart pour rafraîchir ainsi:

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

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.