Próbuję zbudować niestandardowy komponent przy użyciu wielu ng-content
w Angular 6, ale to nie działa i nie mam pojęcia, dlaczego.
To jest mój kod komponentu:
<div class="header-css-class">
<ng-content select="#header"></ng-content>
</div>
<div class="body-css-class">
<ng-content select="#body"></ng-content>
</div>
Próbuję użyć tego składnika w innym miejscu i renderowanie dwa różne wewnątrz kodu HTML body
i nagłówek select
o ng-content
, coś takiego:
<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>
Ale komponent jest renderowany jako pusty.
Czy wiecie, co mogę zrobić źle lub jaki jest najlepszy sposób renderowania dwóch różnych sekcji w tym samym komponencie?
Dzięki!
angular
angular6
angular-components
ng-content
Lucas Santos
źródło
źródło
Odpowiedzi:
header
ibody
zamiast odwołań do szablonów(#header, #body)
.ng-content
zselect
atrybutem takim jakselect="[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>
PRÓBNY
źródło
<div header>
z<ng-container header>
.<div header>
przy<ng-container header>
pracach zbyt.Aby dopasować się do specyfikacji składnika sieci Web . Nawet jeśli to jest Angular. Chodzi o unikanie atrybutów selektora, takich jak dyrektywy Angular lub zarezerwowane atrybuty z innym użyciem. Dlatego po prostu używamy atrybutu „slot”. Zobaczymy
<ng-content select="[slot=foobar]">
jako<slot name="foobar">
.Przykład:
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>
Wynik
Przykład Stackblitz
Możesz użyć dowolnej nazwy, np. „Banan” lub „ryba”. Ale „początek” i „koniec” to dobra konwencja umieszczania elementów przed i po.
źródło
:host
iw::ng-deep
SCSS. Ale to tylko przykład. Zobacz Stackblitz Może::slotted
/::content
będzie również działać. Ale, nie pewne. W sieci znajdziesz więcej informacji na ten temat. Ogólnie rzecz biorąc, należy stylizować tylko sam komponent. I unikaj stylizacji na zewnątrz (globalnie). W przeciwnym razie będziesz mieć niepożądane skutki uboczne.<div class="end"><ng-content></ng-content></div>
Ponieważ ten element jest dostępny w komponencie. Zawartość ng jest tylko pseudoelementem, który jest zastępowany przez zadokowany element na zewnątrz. Musisz więc użyć selektora ng-deep.alternatywnie możesz użyć:
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>
źródło
Uzupełniając inne odpowiedzi:
Można również zrobić to z niestandardowych znaczników (jak
<ion-card>
,<ion-card-header>
i<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>
Otrzymasz komunikat ostrzegawczy, ale zadziała. Możesz pominąć komunikaty ostrzegawcze lub użyć znanych znaczników, takich jak
header
lubfooter
. Jeśli jednak nie podoba ci się żadna z tych metod, powinieneś wybrać jedno z pozostałych rozwiązań.źródło