Semua yang perlu Anda ketahui tentang ng-template, ng-content, ng-container, dan * ngTemplateOutlet di Angular

Itu adalah salah satu hari ketika saya sibuk mengerjakan fitur baru untuk proyek kantor saya. Tiba-tiba, sesuatu menarik perhatian saya:

Saat memeriksa DOM saya melihat ngcontentpenerapannya pada elemen oleh Angular. Hmm… jika mengandung elemen di DOM terakhir, lalu apa gunanya ? Saat itu saya bingung antara dan .

Dalam pencarian untuk mengetahui jawaban atas pertanyaan saya, saya menemukan konsep . Yang mengejutkan saya, ternyata ada juga *ngTemplateOutlet. Saya memulai perjalanan saya mencari kejelasan tentang dua konsep tetapi sekarang saya memiliki empat konsep, terdengar hampir sama!

Apakah Anda pernah mengalami situasi ini? Jika ya, berarti Anda berada di tempat yang tepat. Jadi tanpa basa-basi mari kita bahas satu per satu.

1.

Seperti namanya yang merupakan elemen template yang menggunakan sudut dengan arahan struktural ( *ngIf, *ngFor, [ngSwitch]dan arahan kustom).

Elemen template ini hanya berfungsi jika ada petunjuk struktural . Angular membungkus elemen host (di mana direktif diterapkan) di dalamdan menggunakanDOM yang sudah selesai dengan menggantinya dengan komentar diagnostik.

Pertimbangkan contoh sederhana dari *ngIf:

Ditunjukkan di atas adalah interpretasi Sudut *ngIf. Angular menempatkan elemen host di mana direktif diterapkan di dalamnya dan menjaga host sebagaimana adanya. DOM terakhir mirip dengan yang kita lihat di awal artikel ini:

Pemakaian:

Kami telah melihat bagaimana Angular menggunakan tetapi bagaimana jika kami ingin menggunakannya? Karena elemen-elemen ini hanya bekerja dengan arahan struktural, kita dapat menulis sebagai:

Berikut homeadalah booleanproperti dari komponen yang disetel ke truenilai. Output dari kode di atas di DOM:

Tidak ada yang dirender! :(

Tetapi mengapa kita tidak dapat melihat pesan kita bahkan setelah menggunakan dengan benar dengan petunjuk struktural?

Ini adalah hasil yang diharapkan. Seperti yang telah kita bahas, Angular menggantikan dengan komentar diagnostik. Tidak diragukan lagi kode di atas tidak akan menghasilkan kesalahan apa pun, karena Angular baik-baik saja dengan kasus penggunaan Anda. Anda tidak akan pernah tahu apa yang sebenarnya terjadi di balik layar.

Mari bandingkan dua DOM di atas yang dirender oleh Angular:

Jika Anda perhatikan dengan saksama, ada satu tag komentar tambahan di DOM akhir dari Contoh 2 . Kode yang ditafsirkan Angular adalah:

Angular membungkus host Anda dengan yang lain dan tidak hanya mengubah komentar luar menjadi komentar diagnostik tetapi juga yang dalam! Inilah mengapa Anda tidak bisa melihat pesan Anda.

Untuk menghilangkan ini, ada dua cara untuk mendapatkan hasil yang Anda inginkan:

Metode 1:

Dalam metode ini, Anda memberikan Angular dengan format de-sugared yang tidak perlu diproses lebih lanjut. Kali ini Angular hanya akan mengonversi menjadi komentar tetapi membiarkan konten di dalamnya tidak tersentuh (mereka tidak lagi berada di dalam seperti pada kasus sebelumnya). Dengan demikian, ini akan membuat konten dengan benar.

Untuk mengetahui lebih lanjut tentang cara menggunakan format ini dengan arahan struktural lainnya, lihat artikel ini.

Metode 2:

Ini adalah format yang tidak terlihat dan jarang digunakan (menggunakan dua saudara kandung ). Di sini kami memberikan referensi template ke *ngIfin its thenuntuk memberitahunya template mana yang harus digunakan jika kondisinya benar.

Menggunakan beberapa seperti ini tidak disarankan (Anda dapat menggunakan sebagai gantinya) karena ini bukan untuk apa mereka dimaksudkan. Mereka digunakan sebagai wadah untuk templat yang dapat digunakan kembali di banyak tempat. Kami akan membahas lebih lanjut tentang ini di bagian selanjutnya dari artikel ini.

2.

Pernahkah Anda menulis atau melihat kode yang menyerupai ini:

Alasan mengapa banyak dari kita menulis kode ini adalah ketidakmampuan untuk menggunakan beberapa arahan struktural pada satu elemen host di Angular. Sekarang kode ini berfungsi dengan baik tetapi memperkenalkan beberapa kosong tambahan di DOM jika item.idnilai salah yang mungkin tidak diperlukan.

Seseorang mungkin tidak peduli dengan contoh sederhana seperti ini, tetapi untuk aplikasi besar yang memiliki DOM kompleks (untuk menampilkan puluhan ribu data) ini mungkin menjadi merepotkan karena elemen tersebut mungkin memiliki pendengar yang menyertainya yang akan tetap ada di sana di DOM mendengarkan acara.

Yang lebih buruk lagi adalah tingkat bersarang yang harus Anda lakukan untuk menerapkan gaya (CSS) Anda!

Jangan khawatir, kita harus menyelamatkannya!

Angular adalah elemen pengelompokan yang tidak mengganggu gaya atau tata letak karena Angular tidak meletakkannya di DOM .

Jadi jika kita menulis Contoh 1 kita dengan :

Kami mendapatkan DOM terakhir sebagai:

Lihat kami menyingkirkan itu kosong . Kita harus menggunakan saat kita hanya ingin menerapkan beberapa arahan struktural tanpa memasukkan elemen tambahan apa pun di DOM kita.

Untuk informasi lebih lanjut, lihat dokumen. Ada kasus penggunaan lain yang digunakan untuk memasukkan template secara dinamis ke dalam halaman. Saya akan membahas kasus penggunaan ini di bagian terakhir artikel ini.

3.

Mereka digunakan untuk membuat komponen yang dapat dikonfigurasi. Artinya komponen dapat dikonfigurasi tergantung pada kebutuhan penggunanya. Ini dikenal sebagai Proyeksi Konten . Komponen yang digunakan di pustaka yang diterbitkan memanfaatkan untuk membuat dirinya dapat dikonfigurasi.

Pertimbangkan komponen sederhana :

Konten HTML yang diteruskan dalam tag pembuka dan penutup komponen adalah konten yang akan diproyeksikan. Inilah yang kami sebut Proyeksi Konten . Konten akan dirender di dalam komponen. Hal ini memungkinkan konsumen komponen untuk meneruskan footer kustom apa pun di dalam komponen dan mengontrol dengan tepat bagaimana mereka ingin dirender.

Proyeksi Ganda:

Bagaimana jika Anda dapat memutuskan konten mana yang harus ditempatkan di mana? Daripada setiap konten diproyeksikan di dalam satu , Anda juga dapat mengontrol bagaimana konten akan diproyeksikan dengan selectatribut . Dibutuhkan pemilih elemen untuk memutuskan konten mana yang akan diproyeksikan di dalam tertentu .

Begini caranya:

Kami telah mengubah definisi untuk melakukan proyeksi Multi-konten. The selectatribut memilih jenis konten yang akan diberikan di dalam tertentu . Di sini kita harus selectmerender h1elemen header terlebih dahulu . Jika konten yang diproyeksikan tidak memiliki h1elemen, itu tidak akan merender apa pun. Demikian pula yang kedua selectmencari a div. Sisa konten akan dirender di dalam yang terakhir dengan no select.

Memanggil komponen akan terlihat seperti:

4. * ngTemplateOutlet

… Mereka digunakan sebagai wadah untuk templat yang dapat digunakan kembali di banyak tempat. Kami akan membahas lebih lanjut tentang ini di bagian selanjutnya dari artikel ini.

… Ada kasus penggunaan lain yang digunakan untuk memasukkan template secara dinamis ke dalam halaman. Saya akan membahas kasus penggunaan ini di bagian terakhir artikel ini.

Di bagian inilah kita akan membahas dua poin di atas yang telah disebutkan sebelumnya. *ngTemplateOutletdigunakan untuk dua skenario - untuk menyisipkan template umum di berbagai bagian tampilan terlepas dari loop atau kondisi dan untuk membuat komponen yang sangat dikonfigurasi.

Penggunaan ulang template:

Pertimbangkan tampilan di mana Anda harus menyisipkan template di banyak tempat. Misalnya, logo perusahaan untuk ditempatkan di dalam situs web. Kita dapat mencapainya dengan menulis template untuk logo satu kali dan menggunakannya kembali di mana saja dalam tampilan.

Berikut adalah cuplikan kodenya:

Seperti yang Anda lihat, kami baru saja menulis template logo satu kali dan menggunakannya tiga kali pada halaman yang sama dengan satu baris kode!

*ngTemplateOutletjuga menerima objek konteks yang dapat diteruskan untuk menyesuaikan keluaran template umum. Untuk informasi lebih lanjut tentang objek konteks, lihat dokumen resmi.

Komponen yang dapat disesuaikan:

Kasus penggunaan kedua *ngTemplateOutletadalah komponen yang sangat disesuaikan. Pertimbangkan contoh komponen kami sebelumnya dengan beberapa modifikasi:

Di atas adalah versi modifikasi dari komponen yang menerima tiga sifat masukan -  headerTemplate, bodyTemplate, footerTemplate. Berikut adalah cuplikan untuk project-content.ts:

Apa yang kami coba capai di sini adalah menampilkan header, body, dan footer seperti yang diterima dari komponen induk . Jika salah satu dari mereka tidak disediakan, komponen kami akan menampilkan template default sebagai gantinya. Jadi, membuat komponen yang sangat disesuaikan.

Untuk menggunakan komponen yang baru kami modifikasi:

Ini adalah bagaimana kita akan meneruskan referensi template ke komponen kita. Jika salah satu dari mereka tidak diteruskan maka komponen akan membuat template default.

ng-content vs. * ngTemplateOutlet

Keduanya membantu kami mencapai komponen yang sangat disesuaikan tetapi mana yang harus dipilih dan kapan?

Dapat dilihat dengan jelas bahwa *ngTemplateOutletmemberi kita lebih banyak kekuatan untuk menampilkan templat default jika tidak ada yang disediakan.

Ini tidak terjadi dengan ng-content. Itu membuat konten apa adanya. Maksimal Anda dapat membagi konten dan membuatnya di berbagai lokasi tampilan Anda dengan bantuan selectatribut. Anda tidak dapat merender konten di dalamnya secara bersyarat ng-content. Anda harus menunjukkan konten yang diterima dari orang tua dengan tidak berarti membuat keputusan berdasarkan konten.

Namun, pilihan memilih di antara keduanya sepenuhnya bergantung pada kasus penggunaan Anda. Setidaknya sekarang kami memiliki senjata baru *ngTemplateOutletdi gudang senjata kami yang memberikan kontrol lebih pada konten selain fitur ng-content!