magento2のcheckout_index_index.xmlの「displayArea」と「provider」の意味


回答:


22

何を理解するためにcheckoutProviderしてdisplayAreaいる、あなたは最初にあなたが見ている範囲を理解する必要がありますjsLayout

jsLayoutチェックアウトページ上のJavaScript UI要素のJavaScript構成の束です。を見るとmodule-checkout/view/frontend/templates/onepage.phtml、次のx-magento-init-dataに気付くでしょう。

<script type="text/x-magento-init">
    {
        "#checkout": {
            "Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?>
        }
    }
</script>

これがすべての始まりです。状態:

elementの#checkout場合Magento_Ui/js/core/app、次の情報で-componentを初期化します。...

また、受け取る情報は、レイアウトXMLで作成された情報ですjsLayout。これは、XML内のすべてが- Magento_Ui/js/core/appコンポーネントに渡されることを意味します(プラグイン、レイアウトプロセッサ、および当面の要素は今のところ残しておきます...)

さて、私はmodule-ui/view/base/web/js/core/app.jsこの記事を非常に長くするので、すべてを煮詰める方法について詳細に飛び込むつもりはありませんが、要約はこれです:

  • Magento_Ui/js/core/app-componentが作成されますcheckout-componentを。
  • これuiComponentは、このタイプのコンポーネントになります(これは、独自のカスタムUIコンポーネントを延期するために使用できる非常に汎用的なコンポーネントです。基本的なノックアウトテンプレートのレンダリングなどが付属しています)。
  • それがテンプレートになりMagento_Checkout/web/frontend/template/onepage.htmlます。
  • それは様々な子を作成します(名前のerrorsestimationsteps、など...)
  • steps-childもなりますuiComponent
  • このサイクルは続きます...構成により、さまざまなパラメーターを持つ子が作成されます。

次に、あなたdisplayAreaprovider-question を取得します。上で見たように、すべてがJavaScripクラスにマップされます。の使用法を初めて目にするのdisplayAreasteps、タイプの-component を作成するときuiComponentです。だからuiComponent、の使用を探すための論理的な候補になりますdisplayArea

現在、a uiComponentはタイプのJavaScriptクラスですMagento_Ui/js/lib/core/collection。(これはで調べることができますmodule-ui/view/base/requirejs-config.js)。これはにマッピングされmodule-ui/view/base/web/js/lib/core/collection.jsます。ここでは、次の使用方法を示します。

/**
 * Synchronizes multiple elements arrays with a core '_elems' container.
 * Performs elemets grouping by theirs 'displayArea' property.
 * @private
 *
 * @returns {Collection} Chainable.
 */
_updateCollection: function () {
    var _elems = compact(this._elems),
        grouped;

    grouped = _elems.filter(function (elem) {
        return elem.displayArea && _.isString(elem.displayArea);
    });
    grouped = _.groupBy(grouped, 'displayArea');

    _.each(grouped, this.updateRegion, this);

    this.elems(_elems);

    return this;
},

したがって、これが実際に行うことは、UIComponentの特定のグループにuiComponentを「マッピング」します。これは、phtmlサーバー側でレンダリングされるテンプレートを使用する場合と同様に、XMLレイアウトを操作するだけで、UIコンポーネントをレイアウト内の他の場所に移動できるため、知っておくことが重要です。をオーバーライドするだけでdisplayArea、JavaScript UIコンポーネントを他のどこでもレンダリングできます(ターゲット領域もどこかにレンダリングされる場合)。

今すぐあなたの2番目の質問について:provider。調べたようにdisplayArea、最初にUIコンポーネントを調べ始める必要がありMagento_Checkout/js/view/form/element/emailます。そしてを見ると、requirejs-config.jsついに見つけますmodule-checkout/view/frontend/web/js/view/form/element/email.js

しかし... ... providerはこのクラスでは使用されません。それで、それが拡張するクラスで何かを見つけることができるかどうかを見てみましょう:(ComponentこれはuiComponent再び-classです)。

しかし...いいえprovider。まあ、uiComponent単に拡張するElement(これはにありますmodule-ui/view/base/web/js/lib/core/element/element.js)ので、そこを見てみましょう:

/**
 * Parses 'modules' object and creates
 * async wrappers for specified components.
 *
 * @returns {Element} Chainable.
 */
initModules: function () {
    _.each(this.modules, function (name, property) {
        if (name) {
            this[property] = this.requestModule(name);
        }
    }, this);

    if (!_.isFunction(this.source)) {
        this.source = registry.get(this.provider);
    }

    return this;
},

ビンゴ!プロバイダーは、データをフェッチするソースとして使用されることがわかります。のコンストラクターをElement見ると、デフォルトで空に設定されていることがわかります。

provider: '',

構成に戻ります。ここで構成を読み取ると、アイテムshippingAddressはのコンポーネントでありMagento_Checkout/js/view/shipping、からデータを取得することが理解できますcheckoutProvider

そのため、次の2つの質問が残ります。

  1. どこでcheckoutProvider定義されていますか?
  2. 出荷JavaScriptでどのように使用されますか?

さて、の一番下までスクロールすると、checkout_index_index.xmlバニラにすぎないことがわかりuiComponentます。

<item name="checkoutProvider" xsi:type="array">
    <item name="component" xsi:type="string">uiComponent</item>
</item>

を見るとmodule-checkout/view/frontend/web/js/view/shipping.js、次のように使用されていることがわかります。

registry.async('checkoutProvider')(function (checkoutProvider) {
    var shippingAddressData = checkoutData.getShippingAddressFromData();

    if (shippingAddressData) {
        checkoutProvider.set(
            'shippingAddress',
            $.extend({}, checkoutProvider.get('shippingAddress'), shippingAddressData)
        );
    }
    checkoutProvider.on('shippingAddress', function (shippingAddressData) {
        checkoutData.setShippingAddressFromData(shippingAddressData);
    });
});

正直に言うと、ここで分析が停止します。何が起こっているのかを検索して投資することも難しくなるからです。

私はそれがregistry.async()引数としてコールバック関数ですぐに実行されるメソッドを返すことに関係があることを知っていますが、誰かがこれを説明する必要があります...


*免責事項:間違っている場合は必ず修正してください!上記のいずれも実際に試したことはありませんが、私はMagento 2を使用してほぼ1年間働いています。残念ながら、Magento Oceanの底に潜りたい場合、ドキュメントはあまりありません。


2
それでdisplayAreaとは何ですか?
マリアンゼケシェダジ

1
これは素晴らしい分析です。さらに理解を深めたことがありますか?
LM_Fielding

11

最初の回答から6か月後、何displayAreaがより良い回答を提供できると思います。

私の理解では、すべてはKnockoutsのgetTemplate()-method、getRegion()-method、およびUIコンポーネントの子と一緒になります。この良い例は、vendor/magento/module-checkout/view/frontend/templates/registration.phtmlとを調べているときに見ることができますvendor/magento/module-checkout/view/frontend/web/template/registration.html

ではregistration.phtml、子を持つデフォルトのMagento UIコンポーネントが表示されます。

<script type="text/x-magento-init">
    {
        "#registration": {
            "Magento_Ui/js/core/app": {
               "components": {
                    "registration": {
                        "component": "Magento_Checkout/js/view/registration",
                        "config": {
                            "registrationUrl": "<?php /* @escapeNotVerified */ echo $block->getCreateAccountUrl(); ?>",
                            "email": "<?php /* @escapeNotVerified */ echo $block->getEmailAddress(); ?>"
                        },
                        "children": {
                            "errors": {
                                "component": "Magento_Ui/js/view/messages",
                                "sortOrder": 0,
                                "displayArea": "messages",
                                "config": {
                                    "autoHideTimeOut": -1
                                 }
                            }
                        }
                    }
                }
            }
        }
    }
</script>

-node displayAreaでの使用に注意してくださいchildren。基本的に、この子要素は'messages'と呼ばれる領域にレンダリングする必要があることをKnockoutに伝えます

次に、上部を見てくださいregistration.html

<!-- ko foreach: getRegion('messages') -->
    <!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->

Knockoutコードのこの行は、基本的に、displayArea 'messages'に存在するすべての子要素を反復処理してレンダリングします。

基本的に、あなたが私に尋ねると、命名は少し混乱します。ある場所で「displayArea」を使用し、別の場所で「region」を使用する理由。しかし、おそらく私の仮定はまったく間違っています。おそらく、Magentoのコア開発者がこれにもう少し光を当てることができるでしょうか?


1
これは長い間私を混乱させたものです、私は見続けgetRegion、私の心はただ破裂します。ちなみに両方の答えをありがとう、非常に役立つ!
ベン・クルック

1
まあ、これはちょうど私の2セントです。コア開発者の誰かがこのトピックについて何らかの光を共有できることを願っています。Magento 2のより深い内部構造、特にKnockout / XHR実装全体は、十分に文書化されていないものです。
ゲルバーカーズ

2
同意します。多くのコアファイルを詳しく調べない限り、このスタック交換以外に、何が起こっているのかを知る方法はほとんどありません。
ベン・クルック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.