回答:
何を理解するために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
ます。errors
、estimation
、steps
、など...)steps
-childもなりますuiComponent
。次に、あなたdisplayArea
とprovider
-question を取得します。上で見たように、すべてがJavaScripクラスにマップされます。の使用法を初めて目にするのdisplayArea
はsteps
、タイプの-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つの質問が残ります。
checkoutProvider
定義されていますか?さて、の一番下までスクロールすると、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の底に潜りたい場合、ドキュメントはあまりありません。
最初の回答から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のコア開発者がこれにもう少し光を当てることができるでしょうか?
getRegion
、私の心はただ破裂します。ちなみに両方の答えをありがとう、非常に役立つ!