Widget JS: deux widgets personnalisés ont étendu le même widget parent Magento 2


10

Condition préalable

J'ai 2 widgets personnalisés étendant le même widget parent.

  • Widget parent: Magento_ConfigurableProduct/js/configurable
  • Premier widget personnalisé: Vendor_AModule/js/configurable
  • Deuxième widget personnalisé: Vendor_BModule/js/configurable

Premier widget personnalisé require-config.js:

var config = {
    map: {
        '*': {
            configurable: 'Vendor_AModule/js/configurable'
        }
    }
};

Premier widget personnalisé JS:

define([
    'jquery',
    'mage/translate',
    'Magento_ConfigurableProduct/js/configurable'
], function ($) {
    $.widget('vendor.configurable_awidget', $.mage.configurable, {
        /**
         * {@inheritDoc}
         */
        _configureElement: function (element) {
            this._super(element);
            alert('Custom widget A is triggered!');
        }
    });

    return $.vendor.configurable_awidget;
});

Deuxième widget personnalisé require-config.js:

var config = {
    map: {
        '*': {
            configurable: 'Vendor_BModule/js/configurable'
        }
    }
};

Deuxième widget personnalisé JS:

define([
    'jquery',
    'mage/translate',
    'Magento_ConfigurableProduct/js/configurable'
], function ($) {
    $.widget('vendor.configurable_bwidget', $.mage.configurable, {
        /**
         * {@inheritDoc}
         */
        _configureElement: function (element) {
            this._super(element);
            alert('Custom widget B is triggered!');
        }
    });

    return $.vendor.configurable_bwidget;
});

Étapes à reproduire

J'ouvre une page frontend de produit configurable.

résultat attendu

Je vois les deux Custom widget B is triggered!et Custom widget A is triggered!alerte.

Résultat actuel

Je ne vois que l' Custom widget B is triggered!alerte.

Question

Comment le code doit-il être pour que la page frontend du produit configurable affiche les alertes des deux widgets?

Réponses:


12

Magento 2 a une fonctionnalité moins connue appelée require-js mixinqui est utile pour étendre un module js à partir de plusieurs endroits.

Votre requirejs-config.jsdevrait ressembler à:

var config = {
    'config': {
        'mixins': {
            'Magento_ConfigurableProduct/js/configurable': {
                'Vendor_AModule/js/configurable': true
            }
        }
    }
};

Le fichier js serait alors:

define([
    'jquery',
    'mage/translate'
], function ($) {

    return function (widget) {
        $.widget('vendor.configurable_awidget', widget, {
            /**
             * {@inheritDoc}
             */
            _configureElement: function (element) {
                this._super(element);
                alert('Custom widget A is triggered!');
            }
        });
        return $.vendor.configurable_awidget;
    };
});

Ce js renvoie une fonction qui prend le module cible comme argument et retourne la version étendue. De cette façon, vous pouvez étendre le widget à différents endroits sans remplacement indésirable.


Génial! Infos utiles. THX. J'ai oubliémixin
Khoa TruongDinh

Je ne vois que AWidgetdans votre code, comment postuler BWidget?
Rendy Eko Prastiyo

1
BWidgetserait mis en œuvre de la même manière que AWidget.
Aaron Allen

Merci monsieur, j'ai implémenté votre code et il fonctionne comme il devrait le faire.
Rendy Eko Prastiyo

@AaronAllen, +1 Nice info.
Rakesh Jesadiya

2

Assurez-vous que le module personnalisé est chargé après les autres

<sequence> pour garantir que les fichiers nécessaires à partir d'autres composants sont déjà chargés lors du chargement de votre composant

module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_BModule" setup_version="1.0.1">
        <sequence>
            <module name="Vendor_AModule"/>
        </sequence>
    </module>
</config>

Nous pouvons nous enregistrer app/etc/config.php. Votre module personnalisé doit être de "niveau inférieur" que les autres.

<?php
return array (
  'modules' => 
  array (
    ......
    'Magento_ConfigurableProduct' => 1,
    ......
    'Vendor_AModule' => 1,
    ......
    'Vendor_BModule' => 1,
    ......
  ),
);

Nous pouvons supprimer le module personnalisé de la setup_moduletable. Ensuite, exécutez à nouveau la commande setup upgrade pour réorganiser la séquence du module.

Nous devons nous assurer que le js personnalisé est "de niveau inférieur" que les autres requirejs-config.js.

pub / statique / _requirejs / frontend / Magento / luma / en_US / requirejs-config.js

(function(require){

    ......

    (function() {

        var config = {
            map: {
                '*': {
                    configurable: 'Magento_ConfigurableProduct/js/configurable'
                }
            }
        };
        require.config(config);
    })();

    ......



    (function() {
        var config = {
            map: {
                '*': {
                    configurable: 'Vendor_AModule/js/configurable'
                }
            }
        };
        require.config(config);
    })();

    .....

    (function() {
        var config = {
            map: {
                '*': {
                    configurable : 'Vendor_BModule/js/configurable'
                }
            }
        };
        require.config(config);
    })();

    ......

})(require);

Déclarez le module B

Parce que le widget A a été "remplacé" par le widget Magento par défaut. Donc, dans le module B, nous devons charger le widget A et le "remplacer" .

app / code / Vendeur / BModule / view / frontend / requirejs-config.js

var config = {
    map: {
        '*': {
            configurable : 'Vendor_BModule/js/configurable'
        }
    }
};

app / code / Vendeur / BModule / view / frontend / web / js / configurable.js

define([
    'jquery',
    'mage/translate',
    'Vendor_AModule/js/configurable' // Module A widget
], function ($) {
    $.widget('vendor.configurable_bwidget', $.vendor.configurable_awidget, {
        /**
         * {@inheritDoc}
         */
        _configureElement: function (element) {
            this._super(element);
            alert('Custom widget B is triggered!');
        }
    });

    return $.vendor.configurable_bwidget;
});

Après tout, nous devons réexécuter le déploiement de contenu statique.

Nous pouvons en savoir plus ici: https://learn.jquery.com/jquery-ui/widget-factory/extending-widgets/#using-_super-and-_superapply-to-access-parents


1
Merci pour votre réponse. J'ai implémenté cette méthode il y a un jour, et oui, cela a fonctionné. Mais alors, je me retrouve dans un problème où AModule doit être indépendant de BModule, de sorte que lorsque je désactive AModule, BModule doit toujours fonctionner, vice-versa. Voici où votre réponse ne peut malheureusement pas gérer ce problème.
Rendy Eko Prastiyo
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.