image auteur
Lucas BENTO-VERSACE 6min • 27-09-2023

Angular - Ng-template

Angular - Ng-template

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, découvrez ng-template et toutes les possibilités qu'il vous offre !

À quoi sert ng-template ?

Ng-template est une directive Angular qui s'utilise comme une balise HTML. Elle contient un extrait de DOM.

Ng-template peut servir à définir un contenu de template qui n'est pas rendu par Angular automatiquement, mais que vous pouvez instancier dynamiquement dans votre composant. Cela vous permet d'avoir le contrôle sur la manière et le moment pour afficher le contenu.

Il y a deux façons d'afficher ng-template :

  • L'utilisation de la directive ngTemplateOutlet
  • Utiliser TemplateRef et ViewContainerRef

Ng-template et les directives structurelles

Le principal cas d'usage de ng-template est : l'utilisation des directives structurelles. Et l'utilisation de ng-template est masquée, le développeur ne voit pas que ng-template est utilisé.

En effet, lorsque vous utilisez une directive structurelle (les directives qui s'écrivent avec une * comme *ngIf, *ngFor), cela signifie qu'elle peuvent modifier la structure du DOM pour vous. Et elles réussissent à le faire, en utilisant ng-template en arrière-plan.

Lorsque vous utilisez *ngIf par exemple, Angular crée un ng-template et charge le contenu à l'intérieur de ce dernier et l'affiche selon la valeur de l'expression.

Exemple :

1
<div *ngIf="hero" class="name"></div>
Syntaxe raccourcis ngIf

Est en réalité ceci :

1
2
3
<ng-template [ngIf]="hero">
    <div class="name"></div>
</ng-template>
Syntaxe originale ngIf

C'est la directive ngIf placée sur le ng-template qui se charge d'instancier ou non le contenu du ng-template en temps voulu. Incroyable, n'est-ce pas ?

Manipuler des ng-template

La directive ngTemplateOutlet

ngTemplateOutlet est une directive structurelle qui permet d'instancier un ng-template depuis le template HTML.

Pour l'utiliser il faut d'abord rédiger un ng-template dans le fichier html, et lui affecter une variable de référence de template (ici #varRefTemplate) :

1
2
3
<ng-template #varRefTemplate>
    <p>Bonjour</p>
  </ng-template>
Affectation d'une variable de template

Ensuite, utilisez ngTemplateOutlet sur un ng-container où vous voulez dans votre DOM.

1
2
3
<ng-container *ngTemplateOutlet="varRefTemplate">
    Ce texte ne s'affiche pas car le ng-template est chargé à la place
</ng-container> 
Affectation du template à afficher au ng-container

Le contenu du ng-container est remplacé par le contenu de #varRefTemplate.

Récupérer la TemplateRef et l'envoyer au DOM depuis le composant

Un Ng-template est une instance de la classe TemplateRef. TemplateRef est le type à utiliser pour une référence de ng-template récupérée dans un composant ou une directive. Cela permet de manipuler le template depuis le composant.

Comme précedemment, vous devez d'abord attribuer une variable de référence de template sur le ng-template.

1
2
3
<ng-template #newVarRefTemplate>
    <p>Bonjour</p>
  </ng-template>
Affectation d'une variable de template

Maintenant, utilisez ViewChild pour injecter la variable de référence dans votre composant en tant qu'instance de classe TemplateRef.

1
2
3
4
5
6
7
8
9
10
11
12
@Component({
    selector: 'app-root',
    template: `      
        <ng-template #newVarRefTemplate>
            <p>Bonjour</p>
        </ng-template>
  `})
  export class AppComponent implements OnInit {

      @ViewChild('newVarRefTemplate')
      newVarRefTemplate: TemplateRef<any>;
  }
Injection de la variable de template dans le composant

Maintenant vous devez dire à Angular où l'afficher. Et pour cela, il existe plusieurs méthodes. Pour l'exemple, on va utiliser ViewContainerRef.

ViewContainerRef s'injecte dans un composant ou une directive :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Component({
    selector: 'app-root',
    template: `     
        <h1>Bonjour</h1>  
        <ng-template #newVarRefTemplate>
            <p>Aurevoir</p>
        </ng-template>
  `})
  export class AppComponent implements OnInit {

    constructor(private vref:ViewContainerRef) {}

      @ViewChild('newVarRefTemplate')
      newVarRefTemplate: TemplateRef<any>;
  }
Injection de ViewContainerRef

Dans cet exemple, vref contient une reférence vers la balise de notre composant AppComponent.

Une fois que vous l'avez injecté dans votre composant ou directive, utilisez sa méthode createEmbeddedView pour ajouter le template au composant.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Component({
    selector: 'app-root',
    template: `   
        <h1>Bonjour</h1>   
        <ng-template #newVarRefTemplate>
            <p>Aurevoir</p>
        </ng-template>
  `})
  export class AppComponent implements OnInit, AfterViewInit {

    constructor(private vref:ViewContainerRef) {}

    @ViewChild('newVarRefTemplate')
    newVarRefTemplate: TemplateRef<any>;

    ngAfterViewInit() {
        this.vref.createEmbeddedView(this.newVarRefTemplate);
    }

  }
Ajouter le template au composant pour l'afficher

Et désormais, le contenu du ng-template s'affichera, juste en dessous du composant AppComponent.

Objet de contexte

À l'intérieur du ng-template, vous pouvez référencer du contenu provenant de l'extérieur du template grâce à l'objet de contexte. Cet objet est accessible via les déclarations let comme dans l'exemple ci-dessous.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Component({
    selector: 'app-root',
    template: `      
  <ng-template #estimateTemplate let-bookCounter="estimate">
       <div> Approximativement {{bookCounter}} livres.</div>
  </ng-template>
  <ng-container 
     *ngTemplateOutlet="estimateTemplate;context:objCtx">
  </ng-container>
  `})
  export class AppComponent {
      estimateTotal = 23;
      objCtx = {estimate: this.estimateTotal};
  }
Afficher le template avec des données contextuelles.

Remarquez qu'on passe l'objet de contexte via la directive *ngTemplateOutlet et qu'on utilise les données de cet objet dans le template, après les avoir récupérées via des let-*

Conclusion

J'espère que cet article vous sera utile pour comprendre ce que sont les ng-template et comment les utiliser.

Si vous avez des questions ou des recommandations, laissez un commentaire !

Téléchargez votre Starter Kit Angular

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.

Auteur

image auteur
Lucas BENTO-VERSACE Alternant chez Codewise / Étudiant en développement web lucas.bentoversace@ynov.com
"Alternant chez Codewise, passioné par l'informatique et les technologies depuis mon plus jeune âge. J'ai découvert le monde du web et depuis je ne m'en lasse pas ! Fan de jeux vidéos, de sports et de musiques. "