Maîtriser ng-template pour créer des templates dynamiques, réutilisables et des variables de template avec *ngIf, *ngFor et TemplateRef.
Qu'est-ce que ng-template ?
<ng-template> est une balise Angular qui définit un template qui n'est pas affiché directement. Elle est utilisée comme conteneur pour du contenu conditionnel ou réutilisable.
Cas d'usage:
- Templates conditionnels (affiche seulement si une condition est vraie).
- Boucles dynamiques avec *ngFor.
- Réutilisation de blocs HTML complexes.
- Création de composants génériques et pluggables.
- Gestion du contenu par programmation via TemplateRef.
Utiliser ng-template avec *ngIf
La forme la plus courante : afficher des templates différents selon une condition.
Syntaxe avec then/else:
<div *ngIf="isLoggedIn; then loggedIn else notLoggedIn"></div>
<ng-template #loggedIn>
<p>Bienvenue, {{ user.name }} !</p>
<button (click)="logout()">Déconnexion</button>
</ng-template>
<ng-template #notLoggedIn>
<p>Vous n'êtes pas connecté.</p>
<button (click)="login()">Connexion</button>
</ng-template>
Sans then/else (simple):
<ng-template *ngIf="showAlert">
<div class="alert">Attention!</div>
</ng-template>
Différence avec <div *ngIf>
<div *ngIf="...">— crée une div vide dans le DOM si faux.<ng-template *ngIf="...">— ne crée rien dans le DOM si faux (plus performant).
Variables de template avec let
Crée des variables locales à l'intérieur du template avec le mot-clé let.
Exemple avec *ngIf:
<ng-template [ngIf]="user$ | async as user">
{{ user.firstName }} {{ user.lastName }}
</ng-template>
Exemple avec Observable:
<ng-template let-items="items">
<div *ngFor="let item of items">
{{ item.name }}
</div>
</ng-template>
let, tu évites de répéter le pipe async ou les expressions complexes plusieurs fois.
ng-template avec *ngFor
Affiche un template pour chaque élément d'une liste, avec accès à la variable locale.
Exemple basique:
<ng-template ngFor let-item [ngForOf]="items">
<div class="item-card">
<h3>{{ item.title }}</h3>
<p>{{ item.description }}</p>
</div>
</ng-template>
Avec index et even/odd:
<ng-template
ngFor
let-item [ngForOf]="items"
let-index="index"
let-even="even"
>
<div [class.highlight]="even">
<span class="badge">#{{ index + 1 }}</span>
{{ item.name }}
</div>
</ng-template>
let-item— l'élément courant.let-index— l'index (0-based).let-even— true si l'index est pair.let-odd— true si l'index est impair.let-first— true pour le premier élément.let-last— true pour le dernier élément.
TemplateRef et ViewContainerRef
Accès programmatique aux templates pour créer des composants avancés et pluggables.
Exemple: composant personnalisable
import { Component, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Component({
selector: 'app-dynamic-list',
template: `<div #container></div>`
})
export class DynamicListComponent {
@Input() items: any[] = [];
@Input() itemTemplate?: TemplateRef<any>;
constructor(private viewContainer: ViewContainerRef) {}
ngOnInit() {
this.items.forEach(item => {
this.viewContainer.createEmbeddedView(
this.itemTemplate!,
{ $implicit: item }
);
});
}
}
Utilisation (parent):
<app-dynamic-list [items]="users" [itemTemplate]="userRow"></app-dynamic-list>
<ng-template #userRow let-user>
<div class="user-row">
{{ user.name }} - {{ user.email }}
</div>
</ng-template>
Cas d'usage pratiques
- Tabs dynamiques — chaque tab est un ng-template.
- Accordéon — contenu replié/déplié via ng-template.
- Modales/dialogs — contenu du modal dans un ng-template.
- Listages personnalisés — template réutilisable pour chaque type de vue.
- Conditions complexes — affichage conditionnel sans marquer le DOM inutilement.
- Tables virtualisées — renderiser seulement les lignes visibles.
Bonnes pratiques et performance
- Préférer
ng-templateà<div *ngIf>pour moins de nœuds DOM. - Utiliser
letpour capturer les variables et éviter les expressions répétées. ng-templateest parfait pour les contenus que tu afficheras rarement (lazy-loaded).- Nommer tes templates avec
#template-namepour la clarté (ex:#successTemplate). - Combiner
TemplateRefavec@ContentChildpour les composants génériques. - Ne pas mettre trop de logique dans le template — garder les directives simples.