JS Widget: dois Widgets personalizados estenderam o mesmo pai Widget Magento 2


10

Condição prévia

Eu tenho 2 widgets personalizados que estendem o mesmo widget pai.

  • Widget pai: Magento_ConfigurableProduct/js/configurable
  • Primeiro widget personalizado: Vendor_AModule/js/configurable
  • Segundo widget personalizado: Vendor_BModule/js/configurable

Primeiro widget personalizado require-config.js:

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

Primeiro JS de widget personalizado:

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 JS de widget personalizado:

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

Passos para reproduzir

Abro uma página de front-end de produto configurável.

resultado esperado

Eu vejo os dois Custom widget B is triggered!e Custom widget A is triggered!alerta.

Resultado atual

Eu só vejo Custom widget B is triggered!alerta.

Questão

Como deve ser o código para que a página de front-end do produto configurável exiba alertas dos dois widgets?

Respostas:


12

O Magento 2 possui um recurso menos conhecido, chamado de require-js mixin, útil para estender um módulo js de vários locais.

Você requirejs-config.jsdeve se parecer com:

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

O arquivo js seria então:

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 retorna uma função que pega o módulo de destino como argumento e retorna a versão estendida. Dessa forma, você pode estender o widget em locais diferentes sem substituir indesejadas.


Ótimo! Informações úteis. Valeu. Esquecimixin
Khoa TruongDinh

Só consigo ver AWidgetno seu código como se inscrever BWidget?
Rendy Eko Prastiyo 02/03

1
BWidgetseria implementado da mesma forma que AWidget.
Aaron Allen

Obrigado senhor, eu implementei seu código e ele funciona como deveria.
Rendy Eko Prastiyo #

@AaronAllen, +1 Nice info.
Rakesh Jesadiya

2

Verifique se o módulo personalizado foi carregado após os outros

<sequence> para garantir que os arquivos necessários de outros componentes já estejam carregados quando o componente for carregado

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 fazer o check-in app/etc/config.php. Seu módulo personalizado deve ser "nível mais baixo" que outros.

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

Podemos remover o módulo personalizado da setup_moduletabela. E, em seguida, execute o comando setup upgrade novamente para reordenar a sequência do módulo.

Precisamos garantir que o js personalizado seja "nível mais baixo" do que outros requirejs-config.js.

pub / static / _requirejs / frontend / Magento / luma / pt_BR / 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);

Declare o módulo B

Como o widget A foi "substituído", o widget Magento padrão já. Portanto, no Módulo B, precisamos carregar o widget A e "substituí-lo" .

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

Afinal, precisamos executar a implantação de conteúdo estático novamente.

Podemos ler mais aqui: https://learn.jquery.com/jquery-ui/widget-factory/extending-widgets/#using-_super-and-_superapply-to-access-parents


1
Obrigado pela sua resposta. Eu implementei esse método algum dia atrás e, sim, funcionou. Mas então, eu me encontro em um problema em que o AModule deve ser independente do BModule, de modo que, quando eu desabilito o AModule, o BModule ainda deve funcionar, vice-versa. Aqui é onde sua resposta infelizmente não pode lidar com esse problema.
Rendy Eko Prastiyo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.