JS Widget: dos Widgets personalizados extendieron el mismo Widget principal Magento 2


10

Condición previa

Tengo 2 widgets personalizados que extienden el mismo widget principal.

  • Widget principal: Magento_ConfigurableProduct/js/configurable
  • Primer widget personalizado: Vendor_AModule/js/configurable
  • Segundo widget personalizado: Vendor_BModule/js/configurable

Primer widget personalizado require-config.js:

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

Primer widget personalizado 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;
});

Segundo widget personalizado require-config.js:

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

Segundo widget personalizado 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;
});

pasos para reproducir

Abro una página de interfaz de producto configurable.

Resultado Esperado

Los veo a ambos Custom widget B is triggered!y Custom widget A is triggered!alerta.

Resultado actual

Solo veo Custom widget B is triggered!alerta.

Pregunta

¿Cómo debe ser el código para que la página de interfaz del producto configurable muestre alertas de ambos widgets?

Respuestas:


12

Magento 2 tiene una característica menos conocida llamada require-js mixinque es útil para extender un módulo js desde múltiples lugares.

Tu requirejs-config.jsdebería verse así:

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

El archivo js sería entonces:

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;
    };
});

Este js devuelve una función que toma el módulo de destino como argumento y devuelve la versión extendida. De esta manera, puede extender el widget en diferentes lugares sin anular indeseados.


¡Excelente! Información útil Gracias. Olvidémixin
— Khoa TruongDinh

Solo puedo ver AWidgeten su código, ¿cómo solicitarlo BWidget?
— Rendy Eko Prastiyo

1
BWidgetse implementaría igual que AWidget.
— Aaron Allen

Gracias señor, he implementado su código y funciona como debería.
— Rendy Eko Prastiyo

@AaronAllen, +1 Buena información.
— Rakesh Jesadiya

2

Asegúrese de que el módulo personalizado se cargue después de otros

<sequence> etiqueta para garantizar que los archivos necesarios de otros componentes ya estén cargados cuando se cargue su componente

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>

Podemos comprobar en app/etc/config.php. Su módulo personalizado debe ser de "nivel inferior" que otros.

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

Podemos eliminar el módulo personalizado de la setup_moduletabla. Y luego, ejecute el comando de actualización de configuración nuevamente para reordenar la secuencia del módulo.

Necesitamos asegurarnos de que el js personalizado sea de "nivel inferior" que otros en requirejs-config.js.

pub / static / _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);

Declarar el módulo B

Debido a que el widget A fue "anulado", el widget Magento predeterminado ya. Entonces, en el Módulo B, necesitamos cargar el widget A y "anularlo" .

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

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

app / code / Vendor / 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;
});

Después de todo, necesitamos ejecutar nuevamente la implementación de contenido estático.

Podemos leer más aquí: https://learn.jquery.com/jquery-ui/widget-factory/extending-widgets/#using-_super-and-_superapply-to-access-parents


1
Gracias por tu respuesta. Implementé este método hace algún día, y sí, funcionó. Pero luego, me encuentro en un problema en el que AModule debe ser independiente de BModule, de modo que cuando desactivo AModule, BModule aún debería funcionar, y viceversa. Aquí es donde desafortunadamente su respuesta no puede manejar este problema.
— Rendy Eko Prastiyo
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.