Pour le moment, le HeroesComponent est responsable de l’affichage à la fois de la liste et du détail du héros sélectionné.
A mesure qu’une application grandit, le besoin de modularité grandit avec elle, et il ne devient évidemment plus viable de conserver toutes les fonctionnalités au sein d’un unique composant. Vous voudrez généralement séparer les composants complexes en plusieurs composants plus petits et plus simples, chacun étant centré sur une tâche particulière.
Dans cette section vous allez faire votre premier pas dans cette direction en déplaçant les détails du héros dans un composant séparé et réutilisable, que l’on nommera HeroDetailComponent
.
Le HeroesComponent
servira ainsi uniquement à afficher la liste des héros (comme son nom le laisserait supposer).
1. Créer le HeroDetailComponent
Utilisez le CLI Angular pour générer un nouveau composant nommé hero-detail
ng g c hero-detail
Comme lors de la création du HeroesComponent
, cette commande va générer le HeroDetailComponent
dans son propre répertoire, src/app/hero-detail
. On y retrouvera les 4 fichiers habituels:
-
hero-detail.component.html (template)
-
hero-detail.component.scss (styles)
-
hero-detail.component.spec.ts (tests)
-
hero-detail.component.ts (classe)
La commande ajoute également le HeroDetailComponent
dans le tableau des déclarations d' AppModule
.
Le CLI Angular accepte 2 formats pour la génération de composant:ng generate component hero-detail ng generate component HeroDetail De manière générale, vous pouvez expérimenter les résultats des commandes du CLI sans affecter le projet grâce à l’option --dry-run
|
2. Ecrire le template
Déplacez le HTML qui concerne le héros sélectionné depuis le HeroesComponent
vers le HeroDetailComponent
, en supprimant au passage le code boilerplate généré dans le template du HeroDetailComponent
.
Dans ce code HTML nous faisons référence au selectedHero
. Ce nouveau composant peut présenter n’importe quel héros, renommez donc cet attribut en hero
partout dans le template.
3. Ajouter l’attribut @Input() hero
Le template du HeroDetailComponent
est bindé à l’attribut hero
qui est de type Hero
.
Nous allons déclarer cet attribut hero
en tant qu'Input, car c’est de cette façon que le HeroesComponent
pourra lui communiquer le héros à afficher.
Pour ce faire, nous allons utiliser la syntaxe suivante:
@Input() hero?: Hero;
Et c’est tout ! Ce composant se contente de recevoir un héros et de l’afficher.
4. Afficher le HeroDetailComponent
Le HeroesComponent
va toujours se charger d’afficher la liste des héros et le détail du héros sélectionné, mais en déléguant l’affichage de ce dernier au HeroDetailComponent
.
Ces deux composants vont alors avoir une relation de type parent/enfant.
Le parent HeroesComponent
va contrôler l’enfant HeroDetailComponent
en lui envoyant un nouveau héros à afficher à chaque fois que l’utilisateur sélectionnera un héros dans la liste.
Dans ce cadre, vous n’aurez aucune modification à faire dans la classe du HeroesComponent
, tout va se passer dans le template HTML.
4.1. Mise à jour du template du HeroesComponent
Le sélecteur du HeroDetailComponent
est 'sw-hero-detail'
. Ajoutez donc un élément <sw-hero-detail>
en bas du template du HeroesComponent
, là où le détail était précédemment situé.
Il ne reste plus qu’à binder l’attribut selectedHero
du HeroesComponent
à l’attribut hero
du HeroDetailComponent
. Procédez ainsi:
<sw-hero-detail [hero]="selectedHero"></sw-hero-detail>
[hero]="selectedHero"
est ce qu’on appelle dans Angular un "property binding".
C’est un binding à sens unique (là où [(ngModel)]
est un binding à double sens), depuis l’attribut selectedHero
du HeroesComponent
vers l’attribut hero
du HeroDetailComponent
.
Désormais, lorsque l’utilisateur sélectionne un héros, cela met à jour le selectedHero
, qui à son tour met à jour la valeur de hero
, et le HeroDetailComponent
affiche le nouveau héros.
5. Qu’est-ce qui a changé ?
L’expérience utilisateur n’a pas changé d’un poil après ces modifications. Ce refactoring a pourtant plusieurs bénéfices:
-
Vous avez simplifié le
HeroesComponent
en réduisant ses responsabilités -
Vous pouvez faire évoluer le
HeroDetailComponent
en un éditeur de héros plus complet sans devoir modifier leHeroesComponent
-
Vous pouvez faire évoluer le
HeroesComponent
sans toucher au template du détail -
Vous pouvez réutiliser le
HeroDetailComponent
dans le template de futurs composants.
Cette section est maintenant terminée, vous pouvez passer à l’étape suivante: Services