Le cycle de vie d’un Component

hooks-in-sequenceNous allons maintenant étudier le cycle de vie d'un Component Angular. Pour ceux qui ne connaissent pas le terme de cycle de vie, il s'agit simplement de la définition de toutes les étapes de la naissance du Component à sa mort. Sur le schéma de gauche, vous pouvez voir toutes les étapes du cycle de vie d'un Component. Dans une application Angular, il est utile de pouvoir se greffer à ces différentes étapes. Cela est réalisable grâce à ce que l'on appelle des hooks (ou crochets). Votre Compoment devra implémenter une interface telle que OnChanges et implémenter sa fonction telle que ngOnChanges(changes : SimpleChanges) pour réagir à un évènement. Toutes les interfaces font partie de la librairie @angular/core d'Angular.

Il est a noté que la déclaration des interfaces (et donc l'import) n'est pas obligatoire en soit. Elles sont proposées par TypeScript pour faciliter le développement et la maintenance, mais ne modifie pas le code Javascript lors de la phase de transpilation.

Voici un petit bout de code pour bien comprendre de quoi nous parlons :

Actuellement, Angular indique que les directives suivent le même cycle de vie à l'exception des étapes en bleu (qui sont liées au contenu d'un Component) mais il semble que seuls les hooks liés à la View ne s'appliquent pas au Directives. Affaire à suivre …

 

Sequence du cycle de vie

 

Voici ce qui se cache derrière chaque hook :

 

Hook But et moment
ngOnChanges

Se lance lorsqu'Angular modifie une des propriétés du Component / directive suite à un Property Binding @Input. La méthode reçoit un object SimpleChanges contenant les valeurs courantes et précédentes.

Il est lancé avant ngOnInit et à chaque fois qu'une ou plusieurs propriétés précédées de @Input change.

ngOnInit Initialise le component / directive après qu'Angular ait valorisé les Property Binding @Input. Il n'est lancé qu'une seule fois après le premier ngOnChanges.
ngDoCheck

Détecte et agit sur les changements qu'Angular ne peut ou ne pourra pas détecter lui même. Il permet, en outre, de vérifier les changements dans les directives additionnelement aux algorithmes classiques.

Il est appelé immédiatement après ngOnChanges et ngOnInit.

ngAfterContentInit

Il se lance également après l'initialisation d'un Content ( ng-content ). A partir de ce moment, les propriétés initialisées par @ContentChild et @ContentChildren sont valorisées.

Il n' est appelé qu'une fois après le premier ngDoCheck

ngAfterContentChecked Se lance après le check du Content. 
ngAfterViewInit

Se lance après qu'Angular initialise la vue (template) du Component et les vues enfants.  A partir de ce moment, les propriétés initialisées par @ViewChild et @ViewChildren sont valorisées

Il n'est appelé qu'une seule fois après ngAfterContentChecked.

ngAfterViewChecked Se lance après le check de la vue (template)
ngOnDestroy

Se lance juste avant qu'Angular ne détruise le Component / directive. C'est l'endroit idéal pour desinscrire les Observables et détacher les évènements afin d'éviter les fuites mémoires.

Il est appelé qu'une seule fois avant la destruction du Component / directive.

 

 

Quelques exemples d'implémentations

 

ngOnChanges

Comme vous devez le savoir, le decorator @Input permet de récupérer une donnée venue de l'extérieur dans un Component ou une directive. Il se peut que cette valeur doive être retravaillée afin, par exemple, de  supprimer les espaces avant et après ( trim() ) . Dans ce cas de figure, l'utilisation du mot clé set permet de pratiquer ce genre de traitmement. Par exemple, dans ce component, il est fait usage des set / get  :

 

 

Maintenant si nous devons par un traitement sur tous les input d'un component, il peut être plus judicieux de ne le faire qu'à un seul endroit. C'est ici que la méthode ngOnChanges entre en scène. Voici un exemple de component trackant tous les changements sur ces propriétés pour les stocker dans un tableau :

 

 

Sans cela, notre méthode aurait due être, en partie, dupliquée et aurait nui à la lisibilité du code.

ngAfterContentInit

Pour illustrer cette phase, nous allons prendre l'exemple d'un système d'onglets. Je vous propose maintenant deux nouveaux components : Tab et Tabs. Grâce à cela, nous allons pouvoir créer un système d'onglets très simplement :

 

 

 

En ajoutant le css de bootstrap sur votre index.html, vous obtiendrez le résultat suivant :

 

 

Dans cet exemple, nous avons utilisé le decorator @ContentChild pour récuperer le contenu qui sera fourni par le component parent. Cela impose evidemment que le <ng-content> de TabsComponent soit bien un ensemble de TabComponent : 

@ContentChildren(TabComponent) tabs: QueryList<TabComponent>;

 

Comme pour le @ViewChildren, la propriété tabs n'est pas valorisée de suite, mais elle est setté au niveau du hook AfterContentInit. Grâce à ce décorateur, il est possible de manipuler les propriétés d'un composant qui sera inclu via le mécanisme de <ng-content>. Selon la terminologie, TabComponent est un @ContentChild de TabsComponent.

 

William Koza

William Koza

Consultant Indépendant  
Passionné par la conception et le développement logiciel, j’ai rapidement pris le rôle de Technical Leader lors de mes premiers projets. Ces expériences ont ainsi pu me faire accéder à des rôles d’architecte dans des projets d’envergure. Aujourd'hui, j'exerce mon métier en tant qu'indépendant, et toujours avec la même passion.
William Koza

Les derniers articles par William Koza (tout voir)