답변:
무엇을 이해하기 위해 checkoutProvider
그리고 displayArea
, 당신은 먼저 당신이 찾고있는 범위를 이해해야합니다 jsLayout
.
jsLayout
결제 페이지의 JavaScript UI 요소에 대한 여러 가지 JavaScript 구성입니다. 를 보면 module-checkout/view/frontend/templates/onepage.phtml
다음과 같은 x-magento-init
데이터 가 나타납니다 .
<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
-component (플러그인, 레이아웃 프로세서 및 물건을 떠나는 순간)로 전달됨을 의미합니다 ...
이제이 module-ui/view/base/web/js/core/app.js
게시물을 매우 길게 만들 수 있기 때문에 모든 내용을 정리 하는 방법에 대해 자세히 설명 하지는 않겠지 만 요약은 다음과 같습니다.
Magento_Ui/js/core/app
-component 는 -component를 만듭니다 checkout
.uiComponent
(이것은 사용자 정의 UI 구성 요소를 연기하는 데 사용할 수있는 매우 일반적인 구성 요소입니다. 기본 녹아웃 템플릿 렌더링 및 항목과 함께 제공됨).Magento_Checkout/web/frontend/template/onepage.html
입니다.errors
, estimation
, steps
, 등 ...)steps
-child도 될 것입니다 uiComponent
.이제 당신 displayArea
과 provider
-질문 에 도달하기 : 위에서 보았 듯이 모든 것이 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를 특정 UI 컴포넌트 그룹에 '매핑'하는 것입니다. phtml
서버 측에서 렌더링 되는 템플릿을 사용하는 것처럼 XML 레이아웃을 조작하여 UI 구성 요소를 레이아웃의 다른 위치로 이동할 수 있기 때문에이 점을 알아야 합니다. 를 재정의하면 displayArea
대상 영역도 어딘가에 렌더링되는 경우 JavaScript UI 구성 요소를 다른 곳에서 렌더링 할 수 있습니다.
이제 두 번째 질문 : 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
클래스이다)
그러나 ... 아니요 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
.
따라서 두 가지 질문이 남습니다.
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()
콜백 함수로 인수로 즉시 실행되는 메소드를 반환하는 것과 관련이 있다는 것을 알고 있지만 다른 사람이 이것을 설명해야합니다 ...
* 면책 조항 : 내가 틀렸다면 반드시 정정하십시오! 위의 내용을 실제로 시도하지는 않았지만 거의 1 년 동안 Magento 2와 함께 일해 왔으며 이것이 작동하는 방식이라고 생각합니다. 불행히도 Magento Ocean의 바닥으로 다이빙하고 싶다면 많은 문서가 없습니다.
원래 답변 6 개월 후 나는 무엇에 대해 더 나은 답변을 제공 할 수 있다고 생각 displayArea
합니다.
내 이해에는 모든 것이 UI 구성 요소 getTemplate()
의 getRegion()
Knockouts-방법,-방법 및 자식과 함께 제공됩니다 . 좋은 예는 vendor/magento/module-checkout/view/frontend/templates/registration.phtml
and을 검토 할 때 볼 수 있습니다 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' 라는 영역에서 렌더링되어야한다고 녹아웃에 알립니다 .
이제 상단을 살펴보십시오 registration.html
.
<!-- ko foreach: getRegion('messages') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
이 녹아웃 코드 행의 기본 기능은 displayArea 'messages' 에있는 모든 자식 요소를 반복 하여 렌더링하는 것입니다.
기본적으로, 네가 나에게 물어 보면 이름이 약간 혼란 스럽다. 한 곳에서 'displayArea' 를 사용 하고 다른 곳에서 'region' 을 사용하는 이유는 무엇입니까? 그러나 아마도 내 가정은 완전히 틀렸다. 아마도 Magento 핵심 개발자가 이것에 대해 좀 더 빛을 발할 수 있습니까?
getRegion
러웠습니다. 계속보고 내 마음이 멈 춥니 다. 그건 그렇고, 두 가지 답변에 감사드립니다.