Nous allons découvrir comment mettre en place une communication entre deux Components.
Pour notre besoin, nous souhaitons savoir quand l’utilisateur ajoute un nouvel utilisateur, afin de mettre à jour la liste des éléments.
Deux Components pour séparer les responsabilités
Il est tentant ici de n’avoir qu’un seul Component qui gère les deux. Ainsi, tout le travail est facilité.
Or, du point de vue d’Angular, une règle est presque à respecter sans faute : une fonctionnalité = un Component.
Ici, nous avons donc deux fonctionnalités :
- L’ajout d’un nouvel élément, avec sa Vue dédiée
- Le listing des éléments, avec une Vue dédiée aussi
Communiquer entre deux Components Angular
Or, si nous avons deux composants, comment le Component de listing peut-il savoir quand l’ajout, et donc le clic sur le bouton d’Ajout, a bien eu lieu ?
Il existe plusieurs techniques, dont plusieurs sont proposées par Angular. Par exemple :
- si l’on veut passer un élément du parent à l’enfant,
- détecter les changements de valeur des propriétés d’un des deux composants,
- s’attacher aux changements avec le ngOnChanges,
- …
Ici, nous avons un composant Enfant qui doit communiquer avec son Parent.
Utiliser l’EventEmitter pour respecter le pattern Observer
Une autre approche est d’avoir un fournisseur d’information et un écouteur de ces informations.
Dans notre cas :
- Le composant d’Ajout est le fournisseur d’information : il va émettre l’information d’ajout
- Le composant de Listing va écouter et donc s’attacher à ce fournisseur : il recevra l’information d’ajout
Utilisation du EventEmitter
Pour gérer les événements, Angular propose une notion (qui existe aussi sous Node.js, attention à ne pas confondre) : le EventEmitter.
Mise en place du fournisseur avec EventEmitter
Dans votre composant, déclarer une variable qui va représenter le fournisseur d’événement.
En fait, nous ajoutons ici un custom événement, comme il existe actuellement le (click) sur un bouton.
Import de la classe EventEmitter :
import { Component, OnInit, Output, Input, EventEmitter, OnDestroy } from ‘@angular/core’;
Ajout d’une variable :
itemAdded = new EventEmitter<Hero>();
Or, ici, nous ne pourrons pas permettre de nous attacher à l’événement depuis l’appel dans une Vue.
Ajout de la déclaration @Output()
Pour permettre l’attachement depuis la déclaration dans une Vue, nous devons ainsi utiliser le @Output() :
Import de l’attribut Output :
import { Component, OnInit, Output, Input, EventEmitter, OnDestroy } from ‘@angular/core’;
Ajout de l’attribut :
@Output() itemAdded = new EventEmitter<Hero>();
S’attacher à l’événement depuis une Vue
Grâce à notre paramétrage, nous allons pouvoir, depuis la Vue du Component Parent, nous attacher à l’événement d’ajout.
Et cela s’écrit comme pour l’attachement à un click sur un bouton :
<app-hero-add (itemAdded)= »receiptItemAdded($event) » ></app-hero-add>
Il ne nous reste plus qu’à ajouter la fonction receiptItemAdded dans le Component parent :
receiptItemAdded(item: Item): void {
this.items.push(item);
}