JSウィジェット:2つのカスタムウィジェットが同じ親ウィジェットMagento 2を拡張


10

前提条件

同じ親ウィジェットを拡張する2つのカスタムウィジェットがあります。

  • 親ウィジェット: Magento_ConfigurableProduct/js/configurable
  • 最初のカスタムウィジェット: Vendor_AModule/js/configurable
  • 2番目のカスタムウィジェット: 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;
});

2番目のカスタムウィジェットrequire-config.js

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

2番目のカスタムウィジェット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は、ターゲットモジュールを引数として取り、拡張バージョンを返す関数を返します。このようにして、不要なオーバーライドを行うことなく、さまざまな場所でウィジェットを拡張できます。


すごい!役立つ情報。THX。忘れましたmixin
Khoa TruongDinh 2017年

私はAWidgetあなたのコードでしか見ることができません、どのように適用しますBWidgetか?
Rendy Eko Prastiyo 2017年

1
BWidgetと同じように実装されAWidgetます。
アーロンアレン

ありがとうございます、私はあなたのコードを実装しました、そしてそれはそれがすべきはずのように機能します。
Rendy Eko Prastiyo 2017年

@ AaronAllen、+ 1いい情報。
Rakesh Jesadiya 2017年

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ウィジェットをロードして「オーバーライド」する必要があります

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

結局、静的コンテンツのデプロイを再度実行する必要があります。

詳しくは、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 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.