Untuk apa Impor / Ekspor `defaults` dalam Obyek uiElement?

8

Dalam banyak Magento 2 UI Elemen model tampilan konstruktor, yang defaultsarray akan memiliki importsatau exportsproperti.

return Collection.extend({
    defaults: {
        //...
        imports: {
            rows: '${ $.provider }:data.items'
        },

return Insert.extend({
    defaults: {
        //...
        exports: {
            externalFiltersModifier: '${ $.externalProvider }:params.filters_modifier'
        },

Melihat sumber uiElementmodul,

#File: vendor/magento/module-ui/view/base/web/js/lib/core/element/element.js
    initLinks: function () {
        return this.setListeners(this.listens)
                   .setLinks(this.links, 'imports')
                   .setLinks(this.links, 'exports')
                   .setLinks(this.exports, 'exports')
                   .setLinks(this.imports, 'imports');
    },

Impor / ekspor ini tampaknya ada hubungannya dengan "menghubungkan" informasi antara objek ketika suatu objek dipakai. Namun, tidak jelas bagaimana cara kerja tautan ini (berbasis uiRegistry?) Atau seperti apa sintaksisnya ${ $.provider }:data.items. Jelas string ini menggunakan templat literal yang berkembang menjadi sesuatu seperti

foo_bar:data.items

Namun makna dari string terakhir ini masih misterius.

Adakah yang tahu cara kerja impor / ekspor objek-objek ini?

Alan Storm
sumber
Tidak akan mengirim jawaban karena saya belum benar-benar menggunakannya, tetapi devdocs memberikan sedikit lebih banyak wawasan: devdocs.magento.com/guides/v2.1/ui-components/…
Vinai

Jawaban:

21

Properti ini memungkinkan komponen untuk dihubungkan sehingga mereka dapat berinteraksi satu sama lain. Prinsipnya agak sederhana: mengimpor (mengambil) nilai dari komponen lain atau mengekspor (mengirim) nilai ke komponen lain atau melakukan keduanya.


Catatan: untuk mempertahankan kejelasan dalam jawaban ini, "komponen" adalah objek Javascript yang dikembalikan oleh RequireJS, memiliki nama tertentu, dan dapat diakses dengan nama itu melalui UIRegistry.

Selain itu, semua contoh di bawah ini akan berada di dalam defaults: {}properti komponen.


Dengan prinsip yang diuraikan, mari kita mulai dengan apa yang saya anggap konsep paling mudah:

Impor

Properti ini mengambil nilai dari komponen lain dan menugaskannya ke properti yang ditentukan. Dalam contoh berikut, kami menyatakan impor:

imports: {
    message: '${ $.provider }:data.message'
}

Ketika Magento menginisialisasi komponen ini, Magento akan mencoba untuk memberikan nilai pada messageproperti. Properti ini akan tersedia dalam konteks KnockoutJS. Seperti yang kita tahu , bagaimanapun, itu akan mengevaluasi imports.messagenilai sebagai ekspresi literal template terlebih dahulu. Dalam hal ini, Magento akan menguraikan $.providerdan harus mendapatkan nilai. Sementara itu bisa sejumlah hal, dalam contoh ini dan menurut banyak kasus penggunaan inti Magento, itu adalah nama komponen yang ada di registri UI. Itu akan diuraikan sebelum langkah berikutnya.

Karena messageproperti di importsproperti, itu akan diteruskan ke setLinks()metode di uiElement.initLinks(). The setLinks()metode adalah di Magento/Ui/view/base/web/js/lib/core/element/links.js. Di sana, loop atas semua properti (hanya di messagesini) di objek yang diteruskan ( importsdalam kasus ini). Pada properti itu, ia akan mencoba untuk mentransfer data dari satu komponen ke yang lain.

The transfer()Fungsi adalah tempat berikutnya yang menarik. Di sini, registri dicari untuk komponen yang merupakan "pemilik", dalam hal impor. Komponen ini adalah yang saat ini "memiliki" atau memiliki data dan akan menjadi $.providerdalam contoh di atas. Jika komponen ditemukan, maka akan melanjutkan untuk menghubungkan data dengan setLink()fungsi.

Ada dua hal yang perlu diperhatikan dalam metode itu: pertama, ia menetapkan pendengar acara di properti, dan kedua, itu akan segera mentransfer data jika bendera yang berlaku telah dikirim. Dalam pengujian saya, selalu melewati immediateparameter sehingga transfer terjadi selama inisialisasi. Namun, karena pendengar acara yang dilampirkan pada langkah pertama, itu akan terus memperbarui nilai, jika mereka berubah, sehingga kedua komponen tetap sinkron.

Data kemudian ditetapkan pada (atau, dalam istilah yang lebih sederhana: "dikembalikan ke") komponen yang memiliki imports: {}properti. Seperti yang saya sebutkan sebelumnya, itu kemudian ditugaskan langsung ke properti komponen yang menyatakannya - pada dasarnya this.messagedalam contoh di atas dan tidak this.defaults.imports.message. Akibatnya, data-bind="text: messageharus menampilkan nilai yang dikembalikan dari data.messageproperti komponen yang ditautkan .

Pendekatan ini memungkinkan Anda untuk menentukan apa nama properti di komponen sumber. Dalam contoh di atas, Anda bisa menggunakan alertMessage: ...alih-alih messagesebagai nama properti komponen Anda.

Ekspor

Ekspor adalah kebalikan dari imports. Mereka didasarkan pada fungsi yang sama dengan impor, tetapi alih-alih mengambil data dari satu komponen dan menugaskannya sendiri, ia mengirim data sendiri ke komponen lain. Akibatnya, hampir semuanya berlawanan. Ambil contoh ini:

exports: {
    phoneNumber: '${ $.contactForm }:phone'
}

Dalam contoh ini, setLinks()mengambil nilai dari komponen ini phoneNumberproperti dan memberikan ke bentuk kontak phoneproperti. Itu sama dengan secara eksplisit mendeklarasikan phoneproperti dalam $.contactFormkomponen. Tanpa pengaturan khusus di $.contactForm, Anda dapat mengakses data ini secara langsung. Mungkin seperti ini di template Knockout: data-bind="text: phone.

Tautan

Akhirnya, linksproperti itu sama dengan menyatakan keduanya importsdan exportsuntuk properti yang sama . Sekilas, ini mungkin tampak seperti referensi melingkar. Meskipun demikian, ada kalanya ini bisa membantu. Meskipun saya yakin ada banyak lagi kasus penggunaan, yang dapat saya lihat adalah kemampuan satu komponen untuk memanipulasi data dari komponen lain secara dinamis. Dalam hal ini, ComponentA adalah sumber dari beberapa data dan menampilkannya di halaman. KomponenB perlu memanipulasi data itu dan linkske properti itu. Ia dapat menampilkan data dan memanipulasi data aktual di ComponentA tanpa pernah memperpanjang atau mengubah ComponentA.

Satu hal yang perlu diperhatikan, adalah bahwa, secara default, linksbukan cara untuk menghubungkan dua modul lainnya. Dengan kata lain, ComponentC tidak dapat linkComponentA ke ComponentB. Ini adalah metode sinkronisasi dua komponen secara dua arah.


Menautkan ( imports,, exportsdan links) hampir selalu dapat memfasilitasi fungsi yang ditugaskan ke properti itu juga. Saya berlari ke beberapa perilaku aneh sambil membuat diamati dan menggunakan linkstetapi secara keseluruhan itu bekerja dengan cukup baik.

Tautan menyediakan nilai-nilai yang tersedia dalam ruang lingkup KnockoutJS dan dapat dimanipulasi seperti halnya properti lainnya. Dan, untuk mengulangi jelas: ingat bahwa imports, exports, dan linksobyek kunci selalu mengacu pada sifat dari komponen arus (satu di mana properti-properti dinyatakan), sedangkan menyinggung nilai untuk nama dan sifat-sifat komponen terpencil .


Sebagai kesimpulan, Magento menggunakan fungsi penghubung ini untuk menghubungkan komponen yang berbeda satu sama lain dan ini adalah cara kami dapat mengakses, menyediakan, atau menyinkronkan data dengan komponen lain.

bassplayer7
sumber
Penjelasan hebat @ bassplayer7 - Apakah Anda punya contohnya? Saya mengerti cara kerjanya tetapi untuk kehidupan saya, saya tidak bisa mendapatkan dua komponen UI sederhana saya untuk berbagi KO yang dapat diamati.
Ben Crook
@BenCrook, sayangnya, saya belum melakukan banyak hal untuk sementara waktu jadi saya tidak punya satu pun. Sekarang saya yakin Anda sudah menemukan jawabannya, tetapi saya sarankan bekerja dengan importsdan exportsbukan links. Saya menemukan linkslebih rapuh dan rapuh. Jika Anda menemukan contoh, dapatkah Anda membagikan tautan?
bassplayer7
Saya mencoba dan gagal membuat impor / ekspor / tautan berfungsi, Vinai telah menjawab pertanyaan di sini meskipun saya belum memiliki kesempatan untuk mencobanya.
Ben Crook
Informasi ini akan sangat bagus di dokumen resmi dev. Proses UI UI hanya binatang yang menakutkan.
Nathaniel Rogers