Alain Chautard
Apr 25, 2019 · 4 min read

ng-content is the directive used to achieve transclusion a.k.en innehållsprojektion

om du lärde dig Angular JS innan du bytte till Angular, kanske du känner till termen transclusion. Å andra sidan, om du inte har någon aning om vad transclusion är, är det nya namnet på det i Angular innehållsprojektion, och det är vad vi ska täcka i det här inlägget.

innehållsprojektion består i att överföra en del av DOM-trädet från en överordnad komponent till en underordnad komponent.

det är perfekt att bygga återanvändbara komponenter som dialogrutor, modaler, flikar och liknande.

Här är ett exempel där jag vill skapa ett popup-fönster med anpassningsbart innehåll, och jag skulle vilja ”skicka” det innehållet till popup-fönstret enligt följande:

<app-popup-window ="showPopup" title="Test pop-up"> This is the content of the pop-up (thanks to transclusion aka content projection)</app-popup-window>

Observera att jag också skickar en titel som en ingång till den komponenten. Nu, som standard, skulle ovanstående kod inte projicera innehållet. För att få innehållsprojektion att hända måste vi lägga till ng-content-direktivet någonstans i mallen för barnkomponenten:

<div class="modalW-content">
<div class="modalW-header">
<h2>{{title}}</h2>
</div>
<div class="modalW-body">
<!-- Our content will be projected here -->
<ng-content></ng-content>
</div>
</div>

ng-content fungerar väldigt mycket som router-outlet: Det är ett direktiv som anger var dynamiskt innehåll kommer att laddas.

ett annat sätt att linda huvudet runt innehållsprojektion är att det i princip kommer att ”klippa och klistra in” den genererade HTML från moderkomponenten i HTML-mallen för barnkomponenten och att HTML kommer att ”klistras in” där ng-innehåll finns.

När vi har ovanstående kod på plats, gör popup-fönstret enligt följande:

Du kan hitta den fullständiga koden för det exemplet i denna stackblitz:

kan detta projicerade innehåll vara dynamiskt?

Naturligtvis kan det! Du kan använda alla databindningar, direktiv eller till och med andra komponenter om du vill.

Här är ett exempel:

<app-popup-window ="showPopup" title="Test pop-up">
This is the content of the pop-up.
{{customText}} <br>
I can even pass a child component: <br>
<app-hello></app-hello>
</app-popup-window>

och allt detta fungerar helt bra:

den fullständiga koden för detta andra exempel finns i denna stackblitz:

vad händer om jag vill projicera flera saker på olika platser?

Jag är glad att du frågade. Detta kallas multi-slot innehåll projektion.

låt oss anta att vi vill ändra vårt popup-fönster så att vi kan skicka en anpassad kropp såväl som en anpassad sidfot till den.

Vi kommer att använda två ng-innehållsdirektiv i den komponenten, och nyckeln är att göra dessa två slitsar välja en specifik del av det projicerade innehållet med följande syntax:

<div class="modalW-body">
<ng-content select="body"></ng-content>
</div><div class="modalW-footer">
<ng-content select="footer"></ng-content>
</div>

nu för att skicka innehåll till dessa specifika slitsar, behöver jag bara använda taggar som matchar urvalskriterierna ovan:

<app-popup-window ="showPopup" title="Test pop-up">
<body>
This is the body of the pop-up.
</body>
<footer>
<button (click)="showPopup = false">Close</button>
</footer>
</app-popup-window>

Observera att jag använde kropp och sidfot eftersom de är faktiska HTML-element som är meningsfulla i det sammanhanget. Ändå kan du välja element efter CSS-klass, attributnamn eller vad du vill. Inget behov av att göra det precis som jag gjorde här.

som du kan se fungerar det snyggt:

jag applicerade en annan färg på sidfoten så att vi kan se att innehållet inkluderades i den högra luckan

den fullständiga koden för detta sista exempel finns i denna stackblitz:

mitt namn är Alain chautard. Jag är expert på Google Developer I Angular, samt grundande konsult och tränare på Angular Training där jag hjälper utvecklingsteam att lära sig och bli skickliga med Angular.

behöver du hjälp med Angular? Låt oss planera lite tid att prata.

om du gillade det här inlägget, vänligen klappa för det eller dela det. Din hjälp uppskattas alltid.

Lämna ett svar

Din e-postadress kommer inte publiceras.