Aller au contenu

ngTemplateOutlet

ngTemplateOutlet est une directive qui vous permet de rendre un template dynamiquement dans votre composant. Au lieu de dupliquer du HTML, vous pouvez définir un template une fois et le réutiliser plusieurs fois avec différentes données.

  • ✅ Éviter la duplication de code - Définir le template une fois, l’utiliser plusieurs fois
  • ✅ Rendu dynamique - Basculer entre différents templates à l’exécution
  • ✅ Composants réutilisables - Permettre aux composants parents de personnaliser les templates enfants
  • ✅ Layouts conditionnels - Afficher différentes interfaces selon les conditions
  • ✅ Personnalisation de listes - Permettre un rendu personnalisé des éléments de liste
Cas d’Utilisation Exemple
Patterns UI réutilisables Cartes, éléments de liste, modales
Layouts conditionnels Vues différentes pour utilisateurs connectés/déconnectés
Composants personnalisables Tableaux, listes avec templates de lignes personnalisés
Changement de template Layouts différents selon la vue ou les préférences utilisateur
Éviter la duplication Même structure HTML avec différentes données
import { Component } from '@angular/core';
import { NgTemplateOutlet } from '@angular/common';
@Component({
selector: 'app-template-demo',
standalone: true,
imports: [NgTemplateOutlet],
template: `
<h1>Using ngTemplateOutlet</h1>
<!-- Render the template here -->
<ng-container *ngTemplateOutlet="greetingTemplate"></ng-container>
<!-- Define the template -->
<ng-template #greetingTemplate>
<p>Hello from template!</p>
<p>This can be reused anywhere!</p>
</ng-template>
`
})
export class TemplateDemoComponent {}
@Component({
selector: 'app-album-template',
standalone: true,
imports: [NgTemplateOutlet],
template: `
<!-- Passer des données au template via le contexte -->
<ng-container
*ngTemplateOutlet="albumTemplate; context: {
$implicit: album,
index: 0,
isFeatured: true
}">
</ng-container>
<!-- Template receives data with 'let-' variables -->
<ng-template #albumTemplate let-album let-i="index" let-featured="isFeatured">
<div class="album-card">
<p>Album #{{ i }}: {{ album.name }}</p>
<p>Artist: {{ album.artist }}</p>
<span *ngIf="featured" class="badge">⭐ Featured</span>
</div>
</ng-template>
`
})
export class AlbumTemplateComponent {
album = { name: 'Dark Side of the Moon', artist: 'Pink Floyd' };
}
@Component({
selector: 'app-album-cards',
standalone: true,
imports: [NgTemplateOutlet],
template: `
<!-- Utiliser the same template 3 times with different data -->
<ng-container *ngTemplateOutlet="albumTemplate; context: {
name: 'Dark Side of the Moon',
artist: 'Pink Floyd'
}"></ng-container>
<ng-container *ngTemplateOutlet="albumTemplate; context: {
name: 'Abbey Road',
artist: 'The Beatles'
}"></ng-container>
<ng-container *ngTemplateOutlet="albumTemplate; context: {
name: 'Thriller',
artist: 'Michael Jackson'
}"></ng-container>
<!-- Define template once -->
<ng-template #albumTemplate let-name="name" let-artist="artist">
<div class="album-card">
<h2>{{ name }}</h2>
<p>🎤 {{ artist }}</p>
</div>
</ng-template>
`
})
export class AlbumCardsComponent {}

Result: Three album cards with the same structure but different content, without duplicating HTML.

@Component({
selector: 'app-player-view',
standalone: true,
imports: [NgTemplateOutlet],
template: `
<button (click)="isPlaying = !isPlaying">Toggle Playback</button>
<!-- Show different template based on condition -->
<ng-container *ngTemplateOutlet="
isPlaying ? playingTemplate : pausedTemplate
"></ng-container>
<ng-template #playingTemplate>
<div class="now-playing">
<h2>🎵 Now Playing: {{ trackTitle }}</h2>
<p>Your playlist is active</p>
<button (click)="pause()">⏸️ Pause</button>
</div>
</ng-template>
<ng-template #pausedTemplate>
<div class="paused">
<h2>⏸️ Playback Paused</h2>
<button (click)="play()">▶️ Resume</button>
</div>
</ng-template>
`
})
export class PlayerViewComponent {
isPlaying = false;
trackTitle = 'Bohemian Rhapsody';
play() { this.isPlaying = true; }
pause() { this.isPlaying = false; }
}
import { Component, input, TemplateRef } from '@angular/core';
import { NgTemplateOutlet, NgFor } from '@angular/common';
@Component({
selector: 'app-list',
standalone: true,
imports: [NgTemplateOutlet, NgFor],
template: `
<div class="list-container">
<div *ngFor="let item of items(); let i = index" class="list-item">
<!-- Render cusaum template for each item -->
<ng-container *ngTemplateOutlet="itemTemplate(); context: {
$implicit: item,
index: i
}"></ng-container>
</div>
</div>
`
})
export class ListComponent {
// Basé sur signal inputs
items = input<any[]>([]);
itemTemplate = input.required<TemplateRef<any>>();
}
@Component({
selector: 'app-data-table',
standalone: true,
imports: [NgTemplateOutlet, NgFor],
template: `
<table>
<thead>
<tr>
<th *ngFor="let column of columns()">{{ column.label }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of data()">
<td *ngFor="let column of columns()">
<!-- Render cusaum cell template -->
<ng-container *ngTemplateOutlet="
column.cellTemplate;
context: { $implicit: row, column: column }
"></ng-container>
</td>
</tr>
</tbody>
</table>
`
})
export class DataTableComponent {
// Basé sur signal inputs
columns = input<Column[]>([]);
data = input<any[]>([]);
}
interface Column {
label: string;
cellTemplate: TemplateRef<any>;
}
  • ✅ Utiliser pour la réutilisabilité des templates - Éviter la duplication de HTML
  • ✅ Excellent pour les composants personnalisables - Permettre aux consommateurs de définir l’apparence des éléments
  • ✅ Préférer aux chaînes *ngIf complexes - Plus propre que les conditionnels imbriqués
  • ✅ Utiliser $implicit pour la valeur de contexte principale - Syntaxe plus simple
  • ✅ Combiner avec contentChild() pour des patterns avancés - APIs plus flexibles
  • ❌ Ne pas surutiliser - Les composants simples n’ont pas besoin de templates
  • ❌ Éviter l’imbrication profonde - Garder les templates simples et lisibles
Pattern Cas d’Utilisation
Un template, plusieurs rendus Cartes, alertes, modales
Changement de template Layouts différents selon l’état
Templates fournis par le parent Listes, tableaux, grilles personnalisables
Templates conditionnels Vues connecté/déconnecté, UI admin/utilisateur
Template avec boucles Rendu de liste dynamique
Approche Quand l’Utiliser
ngTemplateOutlet Besoin de réutiliser ou changer de templates dynamiquement
ngIf/Else Logique simple d’affichage/masquage (2 options max)
Component Complex logic, lifecycle hooks needed
ngSwitch Multiple conditions based on single value