Bienvenue sur CodeWise ! Si vous êtes nouveau ici, vous voudrez sans doute découvrir notre Starter Kit Angular : il contient une roadmap du parcours d'un dev Angular, ainsi qu'un cookbook des commandes les plus utiles et un extrait de formation. Cliquez ici pour le télécharger (c’est gratuit !)
Dans cet article vous allez découvrir à quoi sert le ng-container.
Définition ng-container
La balise <ng-container>
est une balise qui peut contenir des directives structurelles mais qui n'est pas rendue (rendering) dans le DOM.
C'est à dire que si vous utilisez cette balise dans un template HTML de composant, elle n'apparaitra pas dans le DOM sur le navigateur de votre utilisateur. Mais quel est l'intérêt d'une balise qui n'apparait pas ?
En HTML pur, cela n'aurait aucun intérêt. Mais si vous utilisez Angular, cela vous permettra d'utiliser des fonctionnalités d'Angular, sans influencer le DOM de votre projet.
Voici 2 cas où la balise <ng-container>
pourra vous être utile.
Dans quel cas l'utiliser ?
Combiner plusieurs directives structurelles
Vous ne pouvez pas utiliser plusieurs directives structurelles sur le même élément.
Par exemple, ce code vous renverrait une erreur :
1
2
3
4
5
<ul>
<li *ngFor="let item of items" *ngIf="item.isValid">
{{ item.name }}
</li>
</ul>
Dans ce code, on essaye d'afficher tous les items valides dans une liste. Pour cela, vous devez utiliser une boucle *ngFor, combinée avec un *ngIf pour ne filtrer que les items valides.
Or, ceci est impossible avec Angular. Etant donné le fonctionnement des directives structurelles, les 2 directives ne peuvent pas se partager un même élément du DOM.
Pour corriger le problème, vous pourriez utiliser une balise qui ne génère pas d'affichage pour encadrer le <li>
et ainsi poser les directives structurelles sur 2 balises différentes :
1
2
3
4
5
6
7
<ul>
<div *ngFor="let item of items">
<li *ngIf="item.isValid">
{{ item.name }}
</li>
</div>
</ul>
Ce code ne vous génèrera pas d'erreur et il rendra le résultat voulu à l'écran.
Mais cette solution n'est pas tout à fait satisfaisante. Vous voyez pourquoi ?
Premièrement, autour de chaque <li>
vous allez devoir effectuer le rendering d'une <div>
qui ne sert à rien au fonctionnement de votre page.
Vous perdez en performances, et le problème s'aggrave si le nombre d'items augmente.
Et deuxièmement, la sémantique HTML est brisée ! Il est interdit de placer une balise <div>
en enfant direct d'une balise <ul>
.
Essayer de passer votre page dans un validateur HTML W3C, vous verrez qu'il juge votre DOM invalide.
Alors comment faire ? Eh bien c'est là que le <ng-container>
entre en jeu.
1
2
3
4
5
6
7
<ul>
<ng-container *ngFor="let item of items">
<li *ngIf="item.isValid">
{{ item.name }}
</li>
</ng-container>
</ul>
La balise <ng-container>
ne rendra pas d'élément dans le DOM ce qui convient parfaitement à notre cas.
On évite ainsi tout problème de performance du rendering, ainsi que le problème de sémantique HTML.
Utiliser avec ngTemplateOutlet
Quand vous utilisez un <ng-template>
pour générer votre DOM avec Angular, vous devez vous y prendre en 2 étapes :
- Déclarer un
<ng-template>
- Le faire charger à différents endroits de votre page avec la directive
ngTemplateOutlet
La directive ngTemplateOutlet
peut s'appliquer à n'importe quel élément, mais Angular vous recommande de l'utiliser avec <ng-container>
.
Ainsi, le contenu du <ng-template>
se retrouve projeté à l'emplacement de la directive sans être nécessairement encadré d'une <div>
ou autre élément HTML.
Par exemple, imaginez une partie du DOM qui doit être répétée à plusieurs endroits de votre template HTML. Vous décidez de définir un <ng-template>
pour éviter la répétition de code.
Voici ce que vous pourriez envisager :
1
2
3
4
5
6
7
8
9
<ng-container *ngTemplateOutlet="tmpl; context: {text: 'Hello'}">
</ng-container>
<ng-container *ngTemplateOutlet="tmpl; context: {text: 'World'}">
</ng-container>
<ng-template #tmpl let-text>
<h1> {{ text }}</h1>
</ng-template>
Le <h1>
n'a été rédigé qu'une fois, mais il sera chargé 2 fois.
Le DOM résultant de ce code est le suivant :
1
2
3
<h1>Hello</h1>
<h1>World</h1>
Grâce au <ng-container>
, vous n'avez que le contenu du template qui a été rendu dans le DOM final.
<ng-template>
n'apparait pas dans le DOM final non plus.
Conclusion
Voilà c'est tout pour le <ng-container>
, n’hésitez pas à laisser un commentaire, en espérant que cela vous a plu !
Sources
- Angular Documentation : ng-container
- Askcodez : ng-container vs ng-template
Téléchargez votre Starter Kit Angular
En souscrivant vous recevrez :
- Une roadmap d'un développeur Angular
- Un cookbook Angular des commandes les plus utiles
- Un extrait de formation
100% gratuit.