Banyak konten-ng

95

Saya mencoba membuat komponen khusus menggunakan beberapa ng-contentdi Angular 6, tetapi ini tidak berfungsi dan saya tidak tahu mengapa.

Ini adalah kode komponen saya:

<div class="header-css-class">
    <ng-content select="#header"></ng-content>
</div>
<div class="body-css-class">
    <ng-content select="#body"></ng-content>
</div>

Saya mencoba untuk menggunakan komponen ini di tempat lain dan membuat dua yang berbeda dalam kode HTML bodydan sundulan selectdari ng-content, sesuatu seperti ini:

<div #header>This should be rendered in header selection of ng-content</div>
<div #body>This should be rendered in body selection of ng-content</div>

Namun komponen tersebut dirender kosong.

Apakah kalian tahu apa yang mungkin saya lakukan salah atau apa cara terbaik untuk membuat dua bagian berbeda dalam komponen yang sama?

Terima kasih!

Lucas Santos
sumber
Maaf, stackoverflow tidak menyimpan potongan kode kedua saya: Kode yang saya gunakan dalam komponen adalah seperti ini: <div #header> This is header content </div> <div #body> This is body content </div>
Lucas Santos

Jawaban:

180
  1. Anda dapat menambahkan atribut dummy headerdan bodysebagai lawan dari referensi template (#header, #body).
  2. Dan transclude menggunakan ng-contentwith selectatribut like select="[header]".

app.comp.html

<app-child>
    <div header >This should be rendered in header selection of ng-content</div>
    <div body >This should be rendered in body selection of ng-content</div>
</app-child>

child.comp.html

<div class="header-css-class">
    <ng-content select="[header]"></ng-content>
</div>
<div class="body-css-class">
    <ng-content select="[body]"></ng-content>
</div>

DEMO

Amit Chigadani
sumber
6
Jika Anda tidak ingin membuat div tambahan atau tag lain, Anda harus menggunakan <ng-container>
sobczi
3
@AmitChigadani Saya percaya @sobczi berarti Anda dapat mengganti <div header>dengan <ng-container header>.
pengguna12893298320392
3
Saya mengonfirmasi mengganti <div header>dengan <ng-container header>karya juga.
azerafati
49

Agar sesuai dengan spesifikasi Komponen Web . Bahkan jika itu Angular. Ini tentang menghindari atribut untuk pemilih seperti arahan Angular atau atribut yang dipesan dengan penggunaan lain. Jadi, kami hanya menggunakan atribut "slot". Kami akan melihat <ng-content select="[slot=foobar]">sebagai <slot name="foobar">.

Contoh:

hello-world.component.html

<ng-content select="[slot=start]"></ng-content>
<span>Hello World</span>
<ng-content select="[slot=end]"></ng-content>

app.component.html

<app-hello-world>
  <span slot="start">This is a </span>
  <span slot="end"> example.</span>
</app-hello-world>

Hasil

This is a Hello World example.

Contoh Stackblitz

Anda bisa menggunakan nama apapun yang Anda inginkan seperti "banana" atau "fish". Tapi "mulai" dan "akhir" adalah kesepakatan yang baik untuk menempatkan elemen sebelum dan sesudah.

Dominik
sumber
Bagaimana cara menanyakan elemen tersebut? dengan slot nama.
Nexeuz
Itu tergantung pada Angular dan pengaturan komponen dan apa yang Anda inginkan. Anda dapat menggunakan ViewChild di TS atau :hostdan ::ng-deepdi SCSS. Tapi ini hanya sebuah contoh. Lihat Stackblitz Mungkin ::slotted/ ::contentjuga akan berfungsi. Tapi tidak yakin. Web akan menawarkan lebih banyak tentang topik ini. Umumnya Anda hanya perlu mengatur gaya komponen itu sendiri. Dan hindari menata barang di luar (global). Jika tidak, Anda akan mengalami efek samping yang tidak diinginkan.
Dominik
Praktik yang baik adalah membungkusnya. Lihat contoh Stackblitz yang diperbarui di komentar terakhir saya. Lihat file html dan css dari komponen tersebut. Anda sebaiknya memilih ini daripada ng-deep. Misalnya <div class="end"><ng-content></ng-content></div>Karena elemen ini dapat diakses di komponen. Ng-content hanyalah sebuah elemen semu yang digantikan oleh elemen berlabuh di luar. Jadi, Anda harus menggunakan pemilih ng-deep.
Dominik
9

sebagai alternatif, Anda dapat menggunakan:

app.comp.html

<app-child>
    <div role="header">This should be rendered in header selection of ng-content</div>
    <div role="body">This should be rendered in body selection of ng-content</div>
</app-child>

child.comp.html

<div class="header-css-class">
    <ng-content select="div[role=header]"></ng-content>
</div>
<div class="body-css-class">
    <ng-content select="div[role=body]"></ng-content>
</div>
Angelo Radici
sumber
4

Melengkapi jawaban lainnya:

Anda juga dapat melakukannya dengan tag kustom (seperti <ion-card>, <ion-card-header>, dan <ion-card-content>).

app.comp.html

<app-child>
    <app-child-header>This should be rendered in header selection of ng-content</app-child-header>
    <app-child-content>This should be rendered in content selection of ng-content</app-child-content>
</app-child>

child.comp.html

<div class="header-css-class">
    <ng-content select="app-child-header"></ng-content>
</div>
<div class="content-css-class">
    <ng-content select="app-child-content"></ng-content>
</div>

Anda akan mendapatkan pesan peringatan, tetapi itu akan berhasil. Anda dapat menyembunyikan pesan peringatan atau menggunakan tag yang dikenal seperti headeratau footer. Namun, jika Anda tidak menyukai salah satu metode ini, Anda harus menggunakan salah satu solusi lain.

Wesley Gonçalves
sumber