Angular - 5.17 Accéder au contenu projeté avec ContentChild

Dans la leçon précédente, nous avons vu ViewChild. Ici, le paragraphe est projeté depuis le composant parent avec ng-content. ViewChild ne peut pas le récupérer, car ce contenu ne fait pas partie de la vue du composant. Nous utilisons donc ContentChild et les hooks de contenu.

Pourquoi ViewChild ne suffit pas

Le paragraphe est défini dans le composant application, puis transmis au composant d'élément serveur grâce à ng-content. Il fait donc partie du contenu projeté, et non de la vue du composant d'élément serveur.

Dans le composant d'élément serveur, ViewChild ne trouve donc pas ce paragraphe. Il faut une autre approche.

Récupérer l'élément avec ContentChild

On ajoute une référence locale sur le paragraphe dans le template du composant application, ici #contentParagraph. ContentChild doit être importé depuis @angular/core, comme ViewChild.

ContentChild reçoit le sélecteur de la référence et stocke l'élément dans une propriété de type ElementRef. Comme pour ViewChild, la valeur n'est disponible qu'après l'initialisation.

import { ContentChild, ElementRef } from '@angular/core';

@ContentChild('contentParagraph') paragraph: ElementRef;

Comprendre les hooks du cycle de vie

La vidéo teste l'accès au paragraphe dans trois hooks. Dans ngOnInit, le paragraphe n'est pas encore initialisé, il ne s'affiche donc rien.

Dans ngAfterContentInit, le contenu projeté est initialisé. Le texte du paragraphe s'affiche alors. C'est donc le bon endroit pour travailler avec ce contenu.

  • ngOnInit : appelé avant que le contenu projeté soit initialisé.
  • ngAfterContentInit : le contenu projeté est initialisé, la référence est accessible.
  • ngAfterViewInit : concerne la vue du composant, donc ViewChild.

En résumé

ContentChild permet de récupérer un élément projeté avec ng-content. On déclare une référence locale, puis on accède à la propriété seulement à partir de ngAfterContentInit. ViewChild concerne la vue du composant, ContentChild concerne le contenu transmis.

Points clés

  • ngAfterContentInit est le premier hook où le contenu projeté est accessible.
  • ContentChild récupère un élément transmis par ng-content.
  • La référence locale est écrite dans le template du composant parent.
  • Dans ngOnInit, la propriété n'a pas encore de valeur.
  • ViewChild cherche dans la vue, ContentChild dans le contenu projeté.

Questions fréquentes

Quelle différence entre ViewChild et ContentChild ?

ViewChild cherche dans le template du composant. ContentChild cherche dans le contenu transmis par le parent avec ng-content.

Pourquoi le log dans ngOnInit n'affiche-t-il rien ?

Le contenu projeté n'est pas encore initialisé à ce stade. La propriété n'a donc pas encore de valeur.

Quand puis-je utiliser la référence ?

À partir de ngAfterContentInit. Avant ce hook, la valeur n'est pas disponible.