JS-Widget: Zwei benutzerdefinierte Widgets haben dasselbe übergeordnete Widget Magento 2 erweitert

10

Voraussetzung

Ich habe 2 benutzerdefinierte Widgets, die dasselbe übergeordnete Widget erweitern.

  • Übergeordnetes Widget: Magento_ConfigurableProduct/js/configurable
  • Erstes benutzerdefiniertes Widget: Vendor_AModule/js/configurable
  • Zweites benutzerdefiniertes Widget: Vendor_BModule/js/configurable

Erstes benutzerdefiniertes Widget require-config.js:

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

Erstes benutzerdefiniertes Widget 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;
});

Zweites benutzerdefiniertes Widget require-config.js:

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

Zweites benutzerdefiniertes Widget 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;
});

Schritte zum Reproduzieren

Ich öffne eine konfigurierbare Produkt-Frontend-Seite.

erwartetes Ergebnis

Ich sehe beides Custom widget B is triggered!und bin Custom widget A is triggered!wachsam.

Tatsächliche Ergebnis

Ich sehe nur Custom widget B is triggered!Alarm.

Frage

Wie sollte der Code sein, damit auf der konfigurierbaren Produkt-Frontend-Seite Warnungen beider Widgets angezeigt werden?

Rendy Eko Prastiyo
quelle

Antworten:

12

Magento 2 verfügt über eine weniger bekannte Funktion namens require-js mixin, die zum Erweitern eines js-Moduls von mehreren Stellen aus nützlich ist.

Du requirejs-config.jssolltest aussehen wie:

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

Die js-Datei wäre dann:

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

Dies gibt eine Funktion zurück, die das Zielmodul als Argument verwendet und die erweiterte Version zurückgibt. Auf diese Weise können Sie das Widget an verschiedenen Stellen erweitern, ohne unerwünschte Überschreibungen vorzunehmen.

Aaron Allen
quelle
Groß! Hilfreiche Infos. Danke. Ich habe vergessenmixin
Khoa TruongDinh
Ich kann nur AWidgetin Ihrem Code sehen, wie man sich bewirbt BWidget.
Rendy Eko Prastiyo
1
BWidgetwürde genauso umgesetzt werden wie AWidget.
Aaron Allen
Vielen Dank, Sir, ich habe Ihren Code implementiert und er funktioniert so, wie er funktionieren sollte.
Rendy Eko Prastiyo
@ AaronAllen, +1 Nette Infos.
Rakesh Jesadiya
2

Stellen Sie sicher, dass das benutzerdefinierte Modul nach anderen geladen wurde

<sequence> Tag, um sicherzustellen, dass benötigte Dateien von anderen Komponenten bereits geladen werden, wenn Ihre Komponente geladen wird

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>

Wir können einchecken app/etc/config.php. Ihr benutzerdefiniertes Modul sollte "niedriger" sein als andere.

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

Wir können das benutzerdefinierte Modul aus der setup_moduleTabelle entfernen . Führen Sie dann den Befehl setup upgrade erneut aus, um die Modulsequenz neu zu ordnen.

Wir müssen sicherstellen, dass das benutzerdefinierte js "niedriger" ist als andere in requirejs-config.js.

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

Deklarieren Sie das Modul B.

Da das A-Widget bereits über das Standard-Magento-Widget "überschrieben" wurde. In Modul B müssen wir also das Widget A laden und es "überschreiben" .

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 / configure.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;
});

Schließlich müssen wir die Bereitstellung statischer Inhalte erneut ausführen.

Wir können hier mehr lesen: https://learn.jquery.com/jquery-ui/widget-factory/extending-widgets/#using-_super-and-_superapply-to-access-parents

Khoa TruongDinh
quelle
1
Danke für deine Antwort. Ich habe diese Methode vor einem Tag implementiert, und ja, es hat funktioniert. Aber dann befinde ich mich in einem Problem, bei dem AModule unabhängig von BModule sein muss, sodass BModule auch funktionieren sollte, wenn ich AModule deaktiviere, und umgekehrt. Hier kann Ihre Antwort dieses Problem leider nicht lösen.
Rendy Eko Prastiyo