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?

Rendy Eko Prastiyo
la source

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.

Aaron Allen
la source
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

Khoa TruongDinh
la source
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