“ displayArea” และ“ ผู้ให้บริการ” ของ checkout_index_index.xml มีความหมายอย่างไรใน magento2


คำตอบ:


22

เพื่อให้เข้าใจถึงสิ่งที่checkoutProviderและเป็นครั้งแรกที่คุณจะต้องเข้าใจถึงขอบเขตที่คุณกำลังมองหาใน:displayAreajsLayout

jsLayoutคือการกำหนดค่า JavaScript จำนวนมากสำหรับองค์ประกอบ JavaScript UI บนหน้าเช็คเอาต์ หากคุณดู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>

นี่คือจุดเริ่มต้นของทุกสิ่ง มันระบุว่า:

สำหรับองค์ประกอบ#checkoutเริ่มต้น - ส่วนMagento_Ui/js/core/appประกอบด้วยข้อมูลต่อไปนี้: ...

และข้อมูลที่ได้รับเป็นข้อมูลที่สร้างขึ้นในรูปแบบ jsLayoutXML: ตอนนี้หมายความว่าทุกอย่างใน XML ของคุณตอนนี้ถูกส่งผ่านไปยังMagento_Ui/js/core/app-component (ปล่อยปลั๊กอินและตัวประมวลผลการจัดวางและสิ่งต่าง ๆ ออกจากสมการในขณะนี้ ... )

ตอนนี้ฉันจะไม่ลงลึกในรายละเอียดmodule-ui/view/base/web/js/core/app.jsว่าจะทำให้ทุกอย่างเดือดลงได้อย่างไรเพราะนั่นจะทำให้โพสต์นี้ยาวมาก แต่บทสรุปก็คือ:

  • - Magento_Ui/js/core/appส่วนประกอบสร้าง - checkoutส่วนประกอบ
  • นี่จะเป็นองค์ประกอบประเภทuiComponent(นี่เป็นส่วนประกอบทั่วไปมากที่สามารถใช้เพื่อเลื่อนองค์ประกอบ UI ที่กำหนดเองของคุณเองมาพร้อมกับการแสดงผลเทมเพลตและสิ่งที่น่าพิศวงพื้นฐาน)
  • Magento_Checkout/web/frontend/template/onepage.htmlมันจะให้เราแม่แบบ
  • มันจะสร้างเด็กต่างๆ (ที่มีชื่อerrors, estimation, stepsฯลฯ ... )
  • เด็กอายุยังจะเป็นstepsuiComponent
  • รอบนี้ยังคงดำเนินต่อไป ... การกำหนดค่าทำให้ลูก ๆ มีพารามิเตอร์ต่าง ๆ

ตอนนี้เพื่อไปที่displayAreaและproviderคำถามของคุณ: ตามที่คุณเห็นด้านบนทุกอย่างจะทำแผนที่กับคลาส JavaScrip ครั้งแรกที่เราเห็นการใช้displayAreaคือเมื่อเราสร้างsteps-component uiComponentซึ่งเป็นชนิดที่ ดังนั้นจะเป็นผู้สมัครตรรกะที่จะมองหาการใช้งานของuiComponentdisplayArea

ตอนนี้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;
},

ดังนั้นสิ่งนี้จะมีผลบังคับใช้คือ 'จับคู่ ui' กับคอมโพเนนต์ UI กลุ่มหนึ่ง สิ่งนี้เป็นสิ่งสำคัญที่ต้องทราบเนื่องจากช่วยให้เราสามารถย้ายส่วนประกอบ UI ไปยังตำแหน่งอื่น ๆ ในโครงร่างโดยเพียงแค่จัดการเลย์เอาต์ XML เช่นเดียวกับที่คุณทำกับphtmlเท็มเพลตที่แสดงผลฝั่งเซิร์ฟเวอร์ เพียงแค่แทนที่displayAreaและคุณสามารถแสดงผลคอมโพเนนต์ UI UI ได้ทุกที่อื่น (เนื่องจากพื้นที่เป้าหมายถูกแสดงผลที่ใดที่หนึ่ง)

ตอนนี้สำหรับคำถามที่สองของคุณ: provider. เช่นเดียวกับที่เราเคยมองขึ้นdisplayAreaเราควรเริ่มมองหาที่ตัวแทน UI Magento_Checkout/js/view/form/element/emailแรกซึ่งเป็น และถ้าเรามองไปที่ในที่สุดเราก็พบว่าrequirejs-config.jsmodule-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/shippingcheckoutProvider

นั่นทำให้เรามีคำถามสองข้อ:

  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 และฉันเชื่อว่านี่เป็นวิธีการทำงาน น่าเสียดายที่ไม่มีเอกสารมากนักหากคุณต้องการดำดิ่งลงสู่ก้นมหาสมุทร


2
displayArea คืออะไร
Marián Zeke Šedaj

1
นี่เป็นการวิเคราะห์ที่ยอดเยี่ยมคุณเคยพัฒนาความเข้าใจเพิ่มเติมหรือไม่?
LM_Fielding

11

6 เดือนหลังจากคำตอบดั้งเดิมของฉันฉันคิดว่าฉันสามารถให้คำตอบที่ดีกว่าในสิ่งที่displayAreaเป็น

ในความเข้าใจของฉันมันมาพร้อมกับ Knockouts ' getTemplate()-method, the getRegion()-method, และ children ใน UI Components เป็นตัวอย่างที่ดีของเรื่องนี้สามารถมองเห็นได้เมื่อคุณกำลังตรวจสอบและvendor/magento/module-checkout/view/frontend/templates/registration.phtmlvendor/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>

หมายเหตุการใช้งานdisplayAreaในchildren-node โดยทั่วไปจะบอกสิ่งที่น่าพิศวงว่าองค์ประกอบเด็กคนนี้ควรจะแสดงผลในภูมิภาคที่เรียกว่า'ข้อความ'

ตอนนี้ดูที่ด้านบนของregistration.html:

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

สิ่งที่เป็นบรรทัดของรหัสที่น่าพิศวงโดยทั่วไปคือ: มันวนซ้ำองค์ประกอบเด็กทั้งหมดที่มีอยู่ใน'ข้อความ' displayArea และทำให้พวกเขา

โดยพื้นฐานแล้วการตั้งชื่อค่อนข้างสับสนถ้าคุณถามฉัน ทำไมคุณถึงใช้'displayArea'ในที่เดียวและ'ภูมิภาค'ในที่อื่น แต่ข้อสันนิษฐานของฉันอาจไม่ถูกต้องทั้งหมด บางทีนักพัฒนาหลักของ Magento อาจส่องแสงเพิ่มเติมเล็กน้อย


1
นี่คือสิ่งที่ทำให้ฉันสับสนมาเป็นเวลานานฉันก็เห็นgetRegionอยู่เรื่อย ๆ ขอบคุณสำหรับคำตอบทั้งสองทางมีประโยชน์มาก!
Ben Crook

1
นี่ก็แค่ 2 เซ็นต์ของฉัน ฉันหวังว่าใครบางคนของนักพัฒนาหลักสามารถแบ่งปันแสงในหัวข้อนี้ สิ่งที่อยู่ลึกลงไปของ Magento 2 และโดยเฉพาะอย่างยิ่งการนำ Knockout / XHR ไปใช้ทั้งหมดเป็นสิ่งที่ไม่ได้รับการบันทึกไว้อย่างดี
Giel Berkers

2
ตกลงเว้นแต่ว่าคุณได้เจาะเข้าไปในไฟล์ core หลาย ๆ ไฟล์ไม่มีวิธีอื่นใดนอกจากการแลกเปลี่ยนแบบสแต็กเพื่อทราบว่าเกิดอะไรขึ้น
Ben Crook
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.