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데이터 가 나타납니다 .

<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.
  • 이주기는 계속됩니다 ... 구성은 다양한 매개 변수를 가진 하위 항목을 만듭니다.

이제 당신 displayAreaprovider-질문 에 도달하기 : 위에서 보았 듯이 모든 것이 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를 특정 UI 컴포넌트 그룹에 '매핑'하는 것입니다. phtml서버 측에서 렌더링 되는 템플릿을 사용하는 것처럼 XML 레이아웃을 조작하여 UI 구성 요소를 레이아웃의 다른 위치로 이동할 수 있기 때문에이 점을 알아야 합니다. 를 재정의하면 displayArea대상 영역도 어딘가에 렌더링되는 경우 JavaScript UI 구성 요소를 다른 곳에서 렌더링 할 수 있습니다.

이제 두 번째 질문 : provider. 살펴본 것처럼 displayAreaUI 구성 요소를 먼저 살펴보아야합니다 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.

따라서 두 가지 질문이 남습니다.

  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()콜백 함수로 인수로 즉시 실행되는 메소드를 반환하는 것과 관련이 있다는 것을 알고 있지만 다른 사람이 이것을 설명해야합니다 ...


* 면책 조항 : 내가 틀렸다면 반드시 정정하십시오! 위의 내용을 실제로 시도하지는 않았지만 거의 1 년 동안 Magento 2와 함께 일해 왔으며 이것이 작동하는 방식이라고 생각합니다. 불행히도 Magento Ocean의 바닥으로 다이빙하고 싶다면 많은 문서가 없습니다.


2
그래서 displayArea는 무엇입니까?
Marián Zeke Šedaj

1
이것은 훌륭한 분석입니다. 당신은 더 많은 이해를 발전시킨 적이 있습니까?
LM_Fielding 2018 년

11

원래 답변 6 개월 후 나는 무엇에 대해 더 나은 답변을 제공 할 수 있다고 생각 displayArea합니다.

내 이해에는 모든 것이 UI 구성 요소 getTemplate()getRegion()Knockouts-방법,-방법 및 자식과 함께 제공됩니다 . 좋은 예는 vendor/magento/module-checkout/view/frontend/templates/registration.phtmland을 검토 할 때 볼 수 있습니다 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 핵심 개발자가 이것에 대해 좀 더 빛을 발할 수 있습니까?


1
이것은 오랫동안 혼란 스 getRegion러웠습니다. 계속보고 내 마음이 멈 춥니 다. 그건 그렇고, 두 가지 답변에 감사드립니다.
벤 크룩

1
글쎄, 이것은 단지 2 센트입니다. 핵심 개발자 중 누군가가이 주제에 대해 약간의 의견을 공유 할 수 있기를 바랍니다. Magento 2의 더 깊은 내부 구조, 특히 전체 Knockout / XHR 구현은 잘 문서화되지 않은 것입니다.
Giel Berkers

2
많은 핵심 파일을 조사하지 않는 한이 스택 교환 이외의 방법으로 지옥이 무슨 일인지 알 수 없습니다.
벤 크룩
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.