Le cycle de vie d'un composant en Angular : que faut t-il retenir avec la renaissance du framework ?

Je suis Ezéchiel Amen AGBLA, Angular Developer Expert & Ionic Developer Expert, passionné par le développement web et mobile. Je mets la lumière sur des notions liées à Angular et à Ionic pour la communauté francophone.
Depuis la sortie de la version 17 du framework Angular, on parle de la renaissance de Angular. Il y a eu beaucoup de changements majeurs depuis la version 16 du framework pour préparer le terrain à cette renaissance. Ces changements majeurs ont rendu le framework davantage attractif et performant. Dans cet article, nous nous intéresserons au cycle de vie d’un composant en Angular afin de mieux comprendre quelques subtilités d’une part et d’autre part, quels sont les changements qui y ont été apportés.
Avant d’entrer dans le vif du sujet, nous essaierons de comprendre ce qu’est le cycle de vie d’un composant.
Le cycle de vie d’un composant en général, peu importe la technologie utilisée représente les différentes étapes par lesquelles le composant passe depuis la création jusqu’à la destruction. En effet, ce processus est très similaire à la vie d’un être humain par exemple. L’homme naît, grandit, vieillit et meurt. C’est comme cela, il faut voir le cycle de vie d’un composant également. En Angular, ces différentes phases sont perceptibles à travers les différentes méthodes que le framework nous offre. Le cycle de vie d'un composant est étroitement lié à la façon dont Angular vérifie les modifications apportées à nos composants au fil du temps. Notre prochain objectif sera décortiquer une à une ces méthodes afin de rendre le plus accessible possible à la compréhension des uns et des autres.
- La méthode
constructor():
Le framework Angular est basé sur le langage TypeScript. Chaque composant Angular n’est rien d’autre qu’une classe TypeScript. Lorsqu’on parle de classe, on parle de la programmation orientée objet. Ainsi, la première méthode qui s’exécute dans une classe c’est le constructeur de la classe qui est constructor.
Dès que le framework Angular crée une instance de notre composant à l’exécution de notre application, c’est la méthode constructor qui s’exécute en premier. On appelle cette étape du cycle de vie d’un composant Angular : création.
- La méthode
ngOnChanges():
Après la phase de création que nous venons de voir précédemment, la prochaine étape c’est la phase : détection de changements (change detection en anglais). La première méthode de cette phase est la méthode ngOnChanges().
La méthode ngOnChanges s'exécute après que les entrées du composant ont été modifiées. En effet, pour jauger de la pertinence de cette méthode et comprendre comment elle fonctionne, il faut la tester sur un composant ayant des inputs.
En Angular, lorsqu’on décide de passer des informations d’un composant A parent vers un composant B enfant, on passe par des inputs au niveau du composant enfant. Lorsque le composant parent A met à jour les inputs du composant enfant B, la méthode ngOnChanges() se déclenche et ce à chaque nouvelle mise à jour des inputs .
- La méthode
ngOnInit():
La deuxième méthode de la phase de détection de changement du cycle de vie d’un composant Angular est la méthode ngOnInit().
La méthode ngOnInit() s'exécute après qu'Angular ait initialisé toutes les entrées (inputs) des composants avec leurs valeurs initiales. La méthode ngOnInit() d'un composant s'exécute exactement une fois.
Cette étape se produit avant que le template HTML du composant ne soit initialisé. Cela signifie que vous pouvez mettre à jour l'état du composant en fonction de ses valeurs d'entrée (input) initiales.
- La méthode
ngDoCheck()
Juste après l’exécution de la méthode ngOnInit(), notre composant demeure toujours dans la phase de détection de changement à travers l’exécution de la méthode ngDoCheck() .
La première fois que la méthode ngDoCheck() s’exécute c’est juste après l’exécution de la méthode ngOnInit(). Ensuite, ngDoCheck() s'exécute avant chaque vérification par Angular des changements apportés au niveau du template HTML de notre composant.
Cette méthode s'exécute très fréquemment et peut avoir un impact significatif sur les performances de votre page. Ainsi, évitons d’utiliser cette méthode autant que possible, ne l'utilisons que lorsque nous n’avons vraiment pas d'autre alternative.
- La méthode
ngAfterContentInit()
Lorsque dans notre composant Angular, nous interagissons avec des content queries à savoir @ContentChild() ou @ContentChildren() , la méthode ngAfterContentInit() s'exécute une seule fois lorsque tous les enfants imbriqués (content queries) dans le composant ont été initialisés.
Nous pouvons donc accéder à l'état initialisé de nos queries mais toute tentative de modification de l'état dans cette méthode entraîne une erreur ExpressionChangedAfterItHasBeenCheckedError.
La méthode ngAfertContentInit() lorsqu’elle est définie, s’exécute juste après le ngDoCheck() .
Pour ceux qui n’ont aucune idée de ce qu’est une content query, voici un exemple :
@Component({
selector: 'custom-toggle',
...
template: `<div>
<ng-content></ng-content>
</div>`
})
export class CustomToggle {
text: string;
}
@Component({
selector: 'custom-expando',
...
template: `<div>
<ng-content></ng-content>
</div>`
})
export class CustomExpando {
@ContentChild(CustomToggle) toggle: CustomToggle;
ngAfterContentInit() {
console.log(this.toggle.text);
}
}
@Component({
selector: 'user-profile',
template: `
<custom-expando>
<custom-toggle>Show</custom-toggle>
</custom-expando>
`
})
export class UserProfile { }
Le composant
custom-toggleest projecté dans le composantcustom-expandoà travers la directiveng-content.Le composant
custom-toggleà son tour est capable de projecter du contenu d’où le texteShowà l’intérieur des balisescustom-togglelors de son utilisation dans le template du composantuser-profile.Lorsqu’on parle de
content query, il faut penser à laprojection de contenueavec la directiveng-content.
- La méthode
ngAfterContentChecked():
La méthode ngAfterContentChecked() est étroitement liée à la méthode ngAfterContentInit(). En effet, lorsque toutes nos content queries sont initialisées, la méthode ngAfterContentChecked() s’exécute pour marquer ces content queries comme étant checked. Cela signifie tout simplement que ces content queries ont été vérifiées pour déterminer si des changements ont eu lieu à leurs différents niveaux.
Cette méthode s'exécute très fréquemment et peut avoir un impact significatif sur les performances de votre page. Ainsi, évitons d’utiliser cette méthode autant que possible, ne l'utilisons que lorsque nous n’avons vraiment pas d'autre alternative.
Bien que nous puissions accéder à l'état mis à jour des content queries ici, toute tentative de modification d'un état dans cette méthode entraîne une erreur ExpressionChangedAfterItHasBeenCheckedError (ExpressionChangedAfterItBeenChecked).
- La méthode
ngAfterViewInit():
Tout comme nous l’avons vu précédemment avec la méthode ngAfterContentInit() , la méthode ngAferViewInit() aussi s’exécute juste après la méthode ngDoCheck() .
En effet, pendant que la méthode ngAfterContentInit() est utilisée pour les content queries , la méthode ngAfterViewInit() est utilisée pour les view queries (@ViewChild() , @ViewChildren().
La méthode ngAfterViewInit() s'exécute une seule fois lorsque tous les enfants imbriqués (view queries) dans le composant ont été initialisés.
Nous pouvons donc accéder à l'état initialisé de nos view queries mais toute tentative de modification de l'état dans cette méthode entraîne une erreur ExpressionChangedAfterItHasBeenCheckedError.
Pour ceux qui n’ont aucune idée de ce qu’est une view query, voici un exemple :
@Component({
selector: 'custom-card-header',
...
})
export class CustomCardHeader {
text: string;
}
@Component({
selector: 'custom-card',
template: '<custom-card-header>Visit sunny California!</custom-card-header>',
})
export class CustomCard {
@ViewChild(CustomCardHeader) header: CustomCardHeader;
ngAfterViewInit() {
console.log(this.header.text);
}
}
Dans le composant parent
CustomCard, on essaie de récupérer le composant enfantCustomCardHeader.Lorsqu’on parle de
view query, il faut penser à uncomposant enfantqu’on essaie de récupérer depuis uncomposant parentdynamiquement.
- La méthode
ngAfterViewChecked():
La méthode ngAfterViewChecked() suit la même logique que la méthode ngAfterContentChecked() . Tout comme la méthode ngAfterContentChecked() est étroitement liée à la méthode ngAfterContentInit() , la méthode ngAfterViewChecked() est aussi liée à la méthode ngAfterViewInit() .
En effet, lorsque toutes nos view queries sont initialisées, la méthode ngAfterViewChecked() s’exécute pour marquer ces view queries comment étant checked. Cela signifie tout simplement que ces view queries ont été vérifiées pour déterminer si des changements ont eu lieu à leurs différents niveaux.
Bien que nous puissions accéder à l'état mis à jour des view queries ici, toute tentative de modification d'un état dans cette méthode entraîne une erreur ExpressionChangedAfterItHasBeenCheckedError (ExpressionChangedAfterItBeenChecked).
- Les méthodes
afterRender()etafterNextRender():
Les méthodes afterNextRender() et afterRender() font parties des nouvelles méthodes ajoutées au cycle de vie d’un composant Angular depuis la version 16.2 du framework.
La méthode afterRender() se déclenche à chaque fois que tous les composants sont chargés dans le DOM*.*
Quant à la méthode afterNextRender(), elle se déclenchera la prochaine fois que tous les composants seront chargés dans le DOM mais une seule fois*.*
- La méthode
ngOnDestroy():
La méthode ngOnDestroy s'exécute une fois juste avant la destruction d'un composant. Angular détruit un composant lorsqu'il n'est plus affiché sur la page, par exemple lorsqu'il est masqué par un NgIf ou lorsqu'on navigue vers une autre page.
En somme, le cycle de vie d’un composant Angular se résume en trois phase à savoir : la phase de création, la phase de détection de changements et le rendering. La phase de rendering a été introduite dans le framework à la sortie de la version 16 du framework. Chacune de ces phases fait appel à des méthodes dans lesquelles nous pouvons gérer des traitements au besoin. Il est très important de maîtriser ces phases afin d’assurer la performance de nos composants Angular.
Pour plus d'informations 👉 Component Lifecycle





