JS窗口小部件:两个自定义窗口小部件扩展了同一父窗口小部件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!警报。

代码应如何使可配置的产品前端页面显示两个小部件的警报?

Answers:


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
Rendy Eko Prastiyo

1
BWidget的实现方式与相同AWidget
亚伦·艾伦

先生,谢谢您,我已经实现了您的代码,它的工作方式与应做的一样。
Rendy Eko Prastiyo

@ AaronAllen,+ 1好信息。
Rakesh Jesadiya

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比中的其他js“更低” 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);

声明模块B

因为A小部件已被“覆盖”,所以默认的Magento小部件已经存在。因此,在模块B中,我们需要加载A小部件并将其“覆盖”

应用/代码/供应商/ BModule /视图/前端/requirejs-config.js

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

应用/代码/供应商/ BModule /视图/前端/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;
});

毕竟,我们需要再次运行静态内容部署。

我们可以在此处阅读更多信息:https : //learn.jquery.com/jquery-ui/widget-factory/extending-widgets/#using-_super-and-_superapply-to-access-parents


1
感谢您的回答。前一天,我已经实现了这种方法,是的,它奏效了。但是然后,我发现自己遇到了一个问题,即AModule必须独立于BModule,这样,当我禁用AModule时,BModule应该仍然可以工作,反之亦然。不幸的是,这是您的答案无法解决此问题的地方。
Rendy Eko Prastiyo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.