apa arti "displayArea" dan "provider" dari checkout_index_index.xml di magento2


Jawaban:


22

Untuk memahami apa checkoutProviderdan displayAreayang, Anda harus terlebih dahulu memahami ruang lingkup yang Anda cari di: jsLayout.

jsLayoutadalah sekelompok konfigurasi JavaScript untuk elemen UI UI di halaman checkout. Jika Anda melihat module-checkout/view/frontend/templates/onepage.phtml, Anda akan melihat data x-magento-init-atau berikut :

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

Di sinilah semuanya dimulai. Ini menyatakan:

Untuk elemen #checkout, inisialisasi Magento_Ui/js/core/app-komponen dengan informasi berikut: ...

Dan informasi yang diterimanya adalah informasi yang dibuat dalam tata letak XML: jsLayout. Sekarang, ini berarti bahwa semua yang ada di XML Anda sekarang diteruskan ke Magento_Ui/js/core/app-komponen (meninggalkan plugin, dan prosesor tata letak dan hal-hal lain dari persamaan untuk saat ini ...)

Sekarang, saya tidak akan membahas secara terperinci bagaimana module-ui/view/base/web/js/core/app.jsmeruntuhkan segalanya, karena itu akan membuat posting ini sangat, sangat panjang, tetapi ringkasannya adalah ini:

  • Komponen Magento_Ui/js/core/app-component menciptakan checkout-komponen.
  • Ini akan menjadi komponen dari tipe uiComponent(ini adalah komponen yang sangat umum yang dapat digunakan untuk menunda komponen UI kustom Anda sendiri. Muncul dengan rendering template knockout dasar dan lainnya).
  • Itu akan kita templat Magento_Checkout/web/frontend/template/onepage.html.
  • Ini akan menciptakan berbagai anak-anak (dengan nama errors, estimation, steps, dll ...)
  • Anak- stepsanak juga akan menjadi uiComponent.
  • Siklus ini berlanjut ... konfigurasi membuat anak-anak dengan berbagai parameter.

Sekarang untuk menuju ke displayAreadan provider-pertanyaan: Seperti yang Anda lihat di atas, semuanya memetakan ke kelas JavaScrip. Pertama kali kita melihat penggunaannya displayAreaadalah ketika kita membuat steps-component, yang merupakan tipe uiComponent. Jadi uiComponentakan menjadi kandidat yang logis untuk mencari penggunaan displayArea.

Sekarang, a uiComponentadalah kelas tipe JavaScript Magento_Ui/js/lib/core/collection. (Anda dapat melihat ini di module-ui/view/base/requirejs-config.js). Ini memetakan ke module-ui/view/base/web/js/lib/core/collection.js. Di sini kita melihat penggunaan berikut:

/**
 * 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;
},

Jadi apa efeknya, ini 'memetakan' komponen lain ke grup komponen UI tertentu. Ini penting untuk diketahui, karena memungkinkan kita untuk memindahkan komponen UI ke lokasi lain dalam tata letak, dengan hanya memanipulasi tata letak XML, sama seperti Anda akan melakukan ini dengan phtmltemplat yang diberikan sisi server. Cukup timpa displayArea, dan Anda dapat membuat Komponen UI JavaScript apa pun di tempat lain (mengingat bahwa area target juga dirender di suatu tempat).

Sekarang untuk pertanyaan kedua: provider. Sama seperti kita telah melihat ke atas displayArea, kita harus mulai melihat Komponen UI terlebih dahulu, yaitu Magento_Checkout/js/view/form/element/email. Dan jika kita melihat requirejs-config.js, akhirnya kita temukan module-checkout/view/frontend/web/js/view/form/element/email.js.

Tapi ... tidak providerdigunakan di kelas ini. Jadi mari kita lihat apakah kita dapat menemukan sesuatu di kelas yang diperluas: Component(yang merupakan uiComponentkelas kita lagi).

Tapi ... tidak providerjuga. Yah, uiComponentcukup memanjang Element(yang terletak di module-ui/view/base/web/js/lib/core/element/element.js), jadi mari kita lihat di sana:

/**
 * 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;
},

Bingo! Ternyata penyedia digunakan sebagai sumber untuk mengambil data dari. Jika kita melihat konstruktor Element, Anda akan melihat bahwa secara default, itu diatur ke kosong:

provider: '',

Jadi kembali ke konfigurasi kita. Jika sekarang kita membaca konfigurasi kita, kita akan mengerti bahwa item tersebut shippingAddressadalah komponen Magento_Checkout/js/view/shipping, yang mengambil datanya dari checkoutProvider.

Jadi itu meninggalkan kita dengan dua pertanyaan:

  1. Di mana checkoutProviderdidefinisikan?
  2. Bagaimana cara digunakan dalam pengiriman JavaScript?

Nah, jika Anda akan menggulir ke bagian bawah checkout_index_index.xml, Anda akan melihat bahwa itu tidak lebih dari vanila uiComponent:

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

Dan jika Anda melihat module-checkout/view/frontend/web/js/view/shipping.js, Anda akan melihat bahwa itu digunakan seperti ini:

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);
    });
});

Sejujurnya: di sinilah analisis saya berhenti, karena bagi saya juga sulit untuk mencari dan menginvestasikan apa yang terjadi, tetapi saya berharap orang lain dapat mengambilnya dari sini ...

Saya tahu itu ada hubungannya dengan registry.async()mengembalikan metode yang akan segera dieksekusi dengan fungsi callback sebagai argumen, tetapi orang lain perlu menjelaskan ini ...


* Penafian: Dengan segala cara, mohon koreksi saya jika saya salah! Belum mencoba salah satu di atas secara nyata, tetapi saya telah bekerja hampir selama satu tahun sekarang dengan Magento 2 dan saya percaya ini adalah cara kerjanya. Sayangnya tidak ada banyak dokumentasi jika Anda ingin menyelam ke dasar Magento Ocean.


2
jadi apa itu displayArea?
Marián Zeke Šedaj

1
Ini adalah analisis yang brilian, apakah Anda pernah mengembangkan pemahaman lebih lanjut?
LM_Fielding

11

6 bulan setelah jawaban awal saya, saya pikir saya bisa memberikan jawaban yang lebih baik tentang apa displayAreaitu.

Dalam pemahaman saya, itu semua datang bersama-sama dengan getTemplate()metode Knockouts , getRegion()-method, dan anak-anak di Komponen UI. Contoh yang baik dari ini dapat dilihat saat Anda memeriksa vendor/magento/module-checkout/view/frontend/templates/registration.phtmldan vendor/magento/module-checkout/view/frontend/web/template/registration.html.

Di registration.phtml, Anda akan melihat Komponen UI Magento default yang memiliki anak:

<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>

Perhatikan penggunaan displayAreadi children-node. Pada dasarnya, ini memberi tahu Knockout bahwa elemen anak ini harus dirender di wilayah yang disebut 'pesan' .

Sekarang lihat bagian atas registration.html:

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

Apa yang dilakukan oleh baris kode Knockout ini, adalah: ia memutari semua elemen anak yang ada di 'pesan' displayArea , dan menerjemahkannya.

Pada dasarnya, penamaannya agak membingungkan jika Anda bertanya kepada saya. Mengapa Anda menggunakan 'displayArea' di satu tempat, dan 'wilayah' di tempat lain. Tapi mungkin asumsi saya sama sekali tidak benar. Mungkin pengembang inti Magento bisa menyinari sedikit hal ini?


1
Inilah yang membingungkan saya begitu lama, saya terus melihat getRegiondan pikiran saya meledak. Omong-omong, terima kasih atas kedua jawaban, sangat membantu!
Ben Crook

1
Nah, ini hanya 2 sen saya. Saya harap seseorang dari pengembang inti dapat berbagi sedikit tentang topik ini. Internal Magento 2 yang lebih dalam, dan khususnya seluruh implementasi Knockout / XHR adalah sesuatu yang belum terdokumentasi dengan baik.
Giel Berkers

2
Setuju, kecuali Anda mempelajari banyak file inti, tidak ada cara lain selain pertukaran tumpukan ini untuk mengetahui apa yang sedang terjadi.
Ben Crook
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.