image auteur
Huber GERARD 8min • 12-03-2021

Angular - Cycle de vie d'un composant

Angular - Cycle de vie d'un composant

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, vous allez découvrir le cycle de vie d'un composant Angular en détails.

Il est nécessaire d'avoir certaines notions pour pouvoir comprendre cet article, cliquez sur ce lien pour apprendre ce qu'est un composant.

Définition

Le cycle de vie correspond aux différentes étapes de la vie d'une instance. Il débute toujours par une instanciation et termine par la destruction de l'instance, donc la désallocation des ressources mémoire qui lui sont affectées.

Un hook (crochet) est une méthode qui s'exécute lors de certains événements liés au cycle de vie. Cela permet à votre app Angular d'exécuter du code JavaScript lors de ces événements.

De plus, cela peut s'avérer utile, par exemple pour lancer un appel vers une API au chargement d'une page ou bien pour libérer une ressource lors de la destruction de l'instance du composant.

Les étapes du cycle de vie d'un composant

Cycle de vie d'un composant Angular

Par exemple, sur ce diagramme, vous observez l'ordre d'enchainement des hooks en vous fiant aux numéros inscrits à côté de chaque étape.

Voici un détail de chacun de ces hooks, dans l'ordre où ils sont appelés.

1. Le constructeur

Le cycle commence par l'appel du constructeur, juste après l'instanciation du Component.

Dans le constructeur, placez uniquement les initialisations de variable locales avec des valeurs simples.

1
2
3
4
constructor() {
    this.title = "Constructor";
    this.details = "Life cycle component";
}
any.component.ts

Ainsi, ne placez aucune initialisation complexe dans le constructeur. Vous voulez des composant qui se construisent sans consommer beaucoup de ressources et de manière sûre.

NgOnChanges - Détecter les changements d'Input

Immédiatement après le constructeur, Angular appelle le hook ngOnChanges(). Il est également appelé après chaque changement d'une des propriétés passées en Input.

1
2
3
4
5
6
7
8
9
10
11
@Input() lastname: string;

constructor() {}

ngOnChanges() {
  this.uppercase(this.lastname);
}

private uppercase(input: string) {
  input = input.toUpperCase();
}
OnChanges.component.ts

NgOnInit - Initialiser le composant

Le hook NgOnInit est déclenché dès que le DOM du composant a fini de charger.

Utilisez la méthode ngOnInit() dans les 2 cas suivants :

  • Vous voulez mettre en place une initialisation complexe (donc hors du constructeur), typiquement appeler une API qui charge les données de votre page.
  • Vous devez modifier l'état de votre component après le chargement des attributs passés en @Input
1
2
3
4
5
6
7
8
9
10
11
12
13
    studentList: Array<any>;

    constructor(private studentService: StudentService){}

    ngOnInit(){
        this.getStudent();
    }

    getStudent(){
        this.studentService
            .getStudentsFromService()
            .subscribe(students =>  this.studentList = students);
    }
OnInit.component.ts

NgDoCheck - Réagir à tous les changements du DOM

Vous souhaitez réagir à un changement du DOM qui est indétectable par vos autres hooks ?

Dans ce cas vous devrez utiliser la méthode ngDoCheck()

Cette méthode vous permet de réagir à tout changement dans la page qui ne serait pas détecté par le framework.

Attention ! Ne l'utilisez pas plus que nécessaire : cette méthode coûte énormément de ressources et peut donc diminuer les performances globales de votre application.

De ce fait, vous ne verrez pas beaucoup ce hook !

NgAfterContent - Détecter les changements de ng-content

La méthode ngAfterContentInit() est déclenchée lorsque le contenu de la balise ng-content est reçu pour la première fois.

Exemple ContentChild

1
2
3
<app-child-component>
    <div #name >Krishna</div>
</app-child-component>
parent.component.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Component({
    selector: 'app-child-component',
    template: '<ng-content></ng-content>',
    styleUrls: ['./new-component.component.scss']
})
export class ChildComponent implements AfterContentInit  {
  
    @ContentChild('name') nameRef: ElementRef;
  
    ngAfterContentInit(): void {
  
        console.log(this.nameRef);
    }
}
child.component.ts

Exemple ContentChildren

1
2
3
4
<app-child-component>
    <div #name >Mahesh</div>
    <div #name >Krishna</div>
</app-child-component>
parent.component.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Component({
    selector: 'app-child-component',
    template: '<ng-content></ng-content>',
    styleUrls: ['./new-component.component.scss']
})
export class ChildComponent implements AfterContentInit  {
  
    @ContentChildren('name') nameRef: QueryList<ElementRef>;
  
    ngAfterContentInit(): void {
  
        console.log(this.nameRef);
    }
}
child.component.ts

Il y a aussi le hook ngAfterContentchecked() qui est déclenché à chaque fois que le contenu de cette balise est modifié dynamiquement.

NgAfterView - Accéder au DOM

La méthode ngAfterViewInit() est déclenchée lorsque le contenu des variables décorées par @ViewChild ou @ViewChildren est reçu pour la première fois.

Exemple ViewChild

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Component({
    selector: 'app-child-component',
    template: '<div #age> 20 </div>',
    styleUrls: ['./new-component.component.scss']
  })
export class ChildComponent implements AfterViewInit  {
  
    @ViewChild('age') ageRef: ElementRef;
  
    ngAfterViewInit(): void {
  
      console.log(this.ageRef);
    }
}
child.component.ts

Exemple ViewChildren

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Component({
    selector: 'app-child-component',
    template: `<div #age>20 </div>
                <div #age>24 </div>`,
    styleUrls: ['./new-component.component.scss']
  })
export class ChildComponent implements AfterViewInit  {
  
    @ViewChildren('age') ageRef: QueryList<ElementRef>;
  
    ngAfterViewInit(): void {
  
      console.log(this.ageRef);
    }
}
child.component.ts

ngAfterViewchecked() est déclenchée à chaque fois que le contenu de ces variables est modifié.

NgOnDestroy - Détruire l'instance proprement

Enfin le hook ngOnDestroy() vous permet de libérer des ressources avant la destruction de l'instance du composant.

  • Appliquez unsubscribe() aux Observables auxquels le composant est souscrit.
  • Arrêtez vos timers.
  • Désouscrivez-vous également des Promise et callbacks qui viennent de services partageables.

En dernier lieu, ngOnDestroy() peut aussi servir à envoyer un Event pour signaler la destruction à un autre Component.

1
2
3
4
5
6
7
8
9
10
11
12
13
export class OnDestroyComponent implements OnInit {

    subscription : Subscription;
  
    ngOnInit(): void {
      var observable = interval(1000);
      this.subscription = observable.subscribe(x => console.log(x));
    }
  
    ngOnDestroy(): void {
      this.subscription.unsubscribe();
    }
}
OnDestroy.component.ts
La prochaine étape, quand vous êtes à l'aise avec le concept de composants : Les services Angular.

Conclusion

Nous venons de voir toutes les étapes d'un cycle de vie d'un Component et les hooks qui y sont associés.

Si il vous reste des questions, n'hésitez pas à nous contacter via cette page !

Sources

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
Huber GERARD Fondateur de CodeWise / Ingénieur en informatique huber.gerard@codewise.fr
"Attiré par la pédagogie et le coaching de développeurs webs, j'ai fondé CodeWise en 2020 dans le but de favoriser l'accès à un savoir technique de qualité dans le milieu du dev web. Mon travail : des fois je code, des fois je forme ! Hormis l'IT, je suis un fan de nature, sports en tous genre et yoga."