Di Angular, komponen adalah direktif khusus, dan fitur khususnya adalah memiliki template (html) dan gaya (css) sendiri. Oleh karena itu, menggunakan komponen dapat membuat kode kita sangat dipisahkan, dapat digunakan kembali, dan mudah diperluas. Komponen biasa didefinisikan sebagai berikut:
demo.component.ts:
demo.component.html:
demo.component.scss:
Saat kita mereferensikan komponen, konten komponen yang diurai dirender:
Misalkan ada kebutuhan bagi komponen untuk menerima konten yang diproyeksikan secara eksternal, yang berarti bahwa komponen akhirnya menyajikan lebih dari sekadar apa yang didefinisikannya. Saat ini, protagonis artikel ini diundangng-konten。
Proyeksi sederhana
Mari kita mulai dengan yang paling sederhana, tambahkan demo.component.html yang dimodifikasi dan demo.component.scss ke demo.component.html, sebagai berikut:
demo.component.html:
demo.component.scss:
Demi efek, warna latar belakang wadah sengaja didefinisikan sebagai oranye.
Pada titik ini kita dapat mentransmisikan konten dari luar saat mereferensikan komponen, dan konten eksternal akan ditampilkan di area oranye:
Proyeksi yang ditargetkan
Jika ada beberapa sekaligus, bagaimana konten eksternal akan diproyeksikan?
Mari kita lihat contoh terlebih dahulu, demi perbedaan, saya menambahkan area biru, demo.component.html yang dimodifikasi dan demo.component.scss sebagai berikut:
demo.component.html:
demo.component.scss:
Untuk mereferensikan komponen:
Pada titik ini, kita akan melihat bahwa konten eksternal diproyeksikan ke area biru:
Tentu saja, jika Anda memasukkan kode area oranye setelah kode area biru, maka konten eksternal akan diproyeksikan ke area oranye:
Jadi dari contoh di atas, kita dapat melihat bahwa jika ada juga yang sederhana , maka konten eksternal akan diproyeksikan di template komponen yang terakhir.
Jadi mengetahui masalah ini, kita mungkin bertanya-tanya, bisakah kita memproyeksikan konten eksternal secara yang ditargetkan? Jawabannya jelas ya.
Untuk mengatasi ini, dukung satupilihAtribut yang memungkinkan Anda memproyeksikan konten tertentu di tempat tertentu. Properti ini mendukung pemilih CSS (pemilih tag, pemilih kelas, pemilih atribut、... ) untuk mencocokkan apa yang Anda inginkan. Jika tidak ada atribut select yang ditetapkan pada ng-content, atribut tersebut akan menerima konten lengkap, atau konten yang tidak cocok dengan elemen ng-content lainnya.
Melihat langsung pada contoh, demo.component.html yang dimodifikasi dan demo.component.scss adalah sebagai berikut:
demo.component.html:
demo.component.scss:
Seperti yang Anda lihat dari kode di atas, area biru akan menerima bagian dari header tag, area merah akan menerima bagian div dengan kelas "demo2", area hijau akan menerima bagian div dengan nama properti "demo3", dan area oranye akan menerima sisa konten eksternal (mulai, saya adalah konten penyematan eksternal, akhir).
Untuk mereferensikan komponen:
Pada titik ini, kita akan melihat konten eksternal yang diproyeksikan ke dalam .
Memperluas pengetahuan
ngProyekSebagai
Sekarang kita tahu bahwa properti select dari ng-content memungkinkan Anda untuk menentukan bahwa konten eksternal diproyeksikan ke dalam .
Untuk memproyeksikan konten dengan benar berdasarkan atribut select, ada batasan - apakah itu header tag, div dengan kelas "demo2", atau div dengan nama properti "demo3", tag ini semua adalah subnode langsung dari tag komponen.
Apa yang akan terjadi jika bukan karena menjadi subnode langsung? Mari kita modifikasi kode yang mereferensikan komponen demo-component, letakkan header tag dalam div, dan modifikasi sebagai berikut:
Pada titik ini, kita melihat bahwa bagian header tab dari konten tidak lagi diproyeksikan ke area biru, tetapi ke area oranye. Alasannya adalah <ng-content select="header"></ng-content> tidak dapat mencocokkan header tag sebelumnya, sehingga bagian konten ini diproyeksikan ke area <ng-content></ng-content> oranye.
Untuk mengatasi masalah ini, kita harus menggunakan properti ngProjectAs, yang dapat diterapkan pada elemen apa pun. Rinciannya adalah sebagai berikut:
Dengan mengatur properti ngProjectAs, div tempat header tag berada menunjuk ke select="header", dan bagian header tag diproyeksikan ke area biru:
<ng-content>Jangan "menghasilkan" konten Lakukan eksperimen Untuk melakukan eksperimen, pertama-tama tentukan komponen demo-child-component:
komponen demo untuk:
Kemudian di demo-component cast demo-child-component:
Pada titik ini, di konsol kita melihat bahwa inisialisasi komponen demo-child-selesai! Kata-kata ini. Tetapi ketika kita mengklik tombol untuk mengganti operasi, inisialisasi komponen demo-child-selesai! Komponen ini tidak lagi dicetak, yang berarti bahwa komponen demo-child-component kami hanya dibuat-instansiasi sekali - tidak pernah dihancurkan dan dibuat ulang.
Mengapa ini terjadi?
Penyebab terjadinya
<ng-content> Itu tidak "memproduksi" konten, itu hanya memproyeksikan konten yang ada. Anda dapat menganggapnya setara dengan metode node.appendChild(el) atau $(node).append(el) di jQuery: dengan metode ini, node tidak dikloning, itu hanya dipindahkan ke lokasi barunya. Oleh karena itu, siklus hidup konten yang diproyeksikan akan terikat ke tempat yang dideklarasikan, bukan ditampilkan di tempatnya.
Ini juga menjelaskan pertanyaan sebelumnya dari prinsip:Jika ada beberapa sekaligus, bagaimana konten eksternal akan diproyeksikan?
Perilaku ini dilakukan karena dua alasan: konsistensi dan kinerja. Apa arti "konsistensi yang diinginkan" bahwa sebagai pengembang, Anda dapat menebak perilaku aplikasi Anda berdasarkan kodenya. Katakanlah saya menulis kode berikut:
Jelas komponen demo-child-component akan dibuat satu kali, tetapi sekarang jika kita menggunakan komponen dari pustaka pihak ketiga:
Jika pustaka pihak ketiga memiliki kendali atas siklus hidup komponen demo-child, saya tidak akan memiliki cara untuk mengetahui berapa kali komponen tersebut telah dibuat. Satu-satunya cara untuk melakukannya adalah dengan melihat kode pustaka pihak ketiga untuk memahami logika pemrosesan internal mereka. Arti mengikat siklus hidup komponen ke komponen aplikasi kita, bukan pembungkus, adalah bahwa pengembang dapat mengontrol bahwa penghitung hanya dibuat satu kali, tanpa mengetahui kode internal pustaka pihak ketiga.
Alasan kinerjalebih penting. Karena ng-content hanyalah elemen yang bergerak, hal itu dapat dilakukan pada waktu kompilasi, bukan pada runtime, yang sangat mengurangi beban kerja aplikasi yang sebenarnya.
Solusi
Agar komponen dapat mengontrol instansiasi subkomponen yang diproyeksikan, kita dapat melakukannya dengan dua cara: dengan menggunakan <ng-template> elemen dan ngTemplateOutlets di sekitar konten kita, atau dengan menggunakan direktif struktur dengan sintaks "*". Untuk kesederhanaan, kita akan menggunakan Sintaks dalam contoh <ng-template> .
komponen demo untuk:
Kemudian kami menyertakan demo-child-component dalam ng-template:
Pada titik ini, ketika kita mengklik tombol untuk beralih, konsol akan dicetakinisialisasi demo-child-component selesai!Kata-kata ini.
|