JS Widget: два пользовательских виджета расширены одним и тем же родительским Widget Magento 2

10

непременное условие

У меня есть 2 пользовательских виджета, расширяющих один родительский виджет.

  • Родительский виджет: Magento_ConfigurableProduct/js/configurable
  • Первый пользовательский виджет: Vendor_AModule/js/configurable
  • Второй пользовательский виджет: Vendor_BModule/js/configurable

Первый пользовательский виджет require-config.js:

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

Первый Пользовательский Виджет 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;
});

Второй пользовательский виджет require-config.js:

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

Второй пользовательский виджет 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;
});

Действия по воспроизведению

Я открываю настраиваемую страницу веб-интерфейса продукта.

ожидаемый результат

Я вижу и то, Custom widget B is triggered!и другое Custom widget A is triggered!.

Фактический результат

Я вижу только Custom widget B is triggered!предупреждение.

Вопрос

Каким должен быть код, чтобы на настраиваемой странице внешнего интерфейса отображались оповещения обоих виджетов?

Ренди Эко Прастийо
источник

Ответы:

12

Magento 2 имеет менее известную функцию под названием require-js, mixinкоторая полезна для расширения модуля js из нескольких мест.

Вы requirejs-config.jsдолжны выглядеть так:

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

Файл js будет:

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

Этот js возвращает функцию, которая принимает целевой модуль в качестве аргумента и возвращает расширенную версию. Таким образом, вы можете расширить виджет в разных местах без нежелательного переопределения.

Аарон Аллен
источник
Большой! Полезная информация Спасибо. Я забылmixin
Khoa TruongDinh
Я могу видеть только AWidgetв вашем коде, как подать заявку BWidget?
Ренди Эко Прастийо,
1
BWidgetбудет реализован так же, как AWidget.
Аарон Аллен
Спасибо, сэр, я реализовал ваш код, и он работает так, как должен.
Ренди Эко Прастийо,
@AaronAllen, +1 Хорошая информация.
Ракеш Джесадия,
2

Убедитесь, что пользовательский модуль загружен после других

<sequence> тег, чтобы гарантировать, что необходимые файлы из других компонентов уже загружены, когда ваш компонент загружается

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>

Мы можем проверить app/etc/config.php. Ваш пользовательский модуль должен быть «более низкого уровня», чем другие.

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

Мы можем удалить пользовательский модуль из setup_moduleтаблицы. А затем снова запустите команду setup upgrade, чтобы изменить порядок последовательности модулей.

Мы должны убедиться, что пользовательский JS "ниже уровня", чем другие в requirejs-config.js.

PUB / статический / _requirejs / интерфейс / Magento / яркостный / 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);

Объявить модуль B

Потому что виджет A уже «переопределен» по умолчанию для виджета Magento. Итак, в модуле B нам нужно загрузить виджет A и «переопределить» его .

Приложение / код / ​​Vendor / BModule / просмотр / интерфейс / requirejs-config.js

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

Приложение / код / ​​Vendor / BModule / вид / интерфейс / веб / 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;
});

В конце концов, нам нужно снова запустить развертывание статического контента.

Мы можем прочитать больше здесь: https://learn.jquery.com/jquery-ui/widget-factory/extending-widgets/#using-_super-and-_superapply-to-access-parents

Хоа ТруонгДинь
источник
1
Спасибо за Ваш ответ. Я реализовал этот метод однажды назад, и да, он работал. Но затем я нахожусь в проблеме, когда AModule должен быть независимым от BModule, так что, когда я отключаю AModule, BModule все равно должен работать, и наоборот. Вот где ваш ответ, к сожалению, не может решить эту проблему.
Рэнди Эко Прастийо