JS Widget: два користувацькі віджети розширено один і той же батьківський віджет Magento 2


10

Передумова

У мене є два користувацькі віджети, що розширюють той самий батьківський віджет.

  • Батьківський віджет: 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 має менш відому функцію, яку називають requ-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таблиці. А потім знову запустіть команду оновлення установки, щоб повторно замовити послідовність модулів.

Нам потрібно переконатися, що користувальницькі js "нижчого рівня", ніж інші requirejs-config.js.

pub / static / _requirejs / frontend / Magento / luma / en_US / Requjs-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 і «переокремити» його .

app / code / Постачальник / BModule / view / frontend / Requjs-config.js

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

app / code / Постачальник / BModule / view / frontend / web / js / configigurable.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 повинен працювати, навпаки. Ось де ваша відповідь, на жаль, не вдається вирішити цю проблему.
Ренді Еко Прастійо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.