Écoutez le template
Pour qu'une application soit dynamique, il faut que l'utilisateur puisse interagir avec elle. Vous allez maintenant réagir à un événement venant du template avec du comportement TypeScript, en ajoutant un bouton "Oh Snap !".
Ajoutez un bouton avec le texte "Oh Snap!" à côté du nombre de snaps dans votre component :
Oh Snap!
🤌 {{ snaps }}
Maintenant, il faut créer une méthode dans le TypeScript de votre component qui sera déclenchée au clic sur ce bouton. Quel est le comportement auquel on s'attend ici ?
Une première idée serait d'incrémenter le nombre de snaps du FaceSnap. Commençons par ça. Ajoutez la méthode suivante dans le TS du component en dessous de la méthode ngOnInit()
:
onAddSnap() {
this.snaps++;
}
Il faut maintenant lier cette méthode au clic sur le bouton avec la liaison par événement, ou event binding. Là où vous avez utilisé des crochets pour lier aux attributs, vous allez utiliser des parenthèses ()
pour lier aux événements :
(click)="onAddSnap()"Oh Snap!
Maintenant, quand vous cliquez sur le bouton dans le template, vous voyez le nombre de snaps augmenter ! D'ailleurs, ce comportement montre bien le côté dynamique d'Angular : quand la propriété de la classe est modifiée, cette modification est reflétée dans le DOM !
Mais on peut faire mieux !
À vous de jouer
Disons que le comportement que l'on souhaite, c'est qu'un utilisateur ne puisse ajouter qu'un seul snap par image (comme les Likes sur beaucoup d'autres plateformes). Si l'utilisateur a déjà "snapped" une image, le texte du bouton doit être "Oops, un Snap!", et cliquer dessus doit "retirer" le snap (réduire les snaps de 1), auquel moment le bouton réaffiche "Oh Snap!", et retrouve son comportement d'origine.
Je vous propose d'essayer d'implémenter cette fonctionnalité. Vous avez déjà tous les outils dont vous aurez besoin. Je vais inclure deux indices dans la vidéo ci-dessous (et dans le texte plus bas) si vous avez besoin d'un coup de pouce !
Les indices :
vous pouvez ajouter des propriétés à la classe, dont potentiellement une qui enregistrera si l'utilisateur a déjà snapped ;
la méthode
onAddSnap()
aura besoin de plus de logique pour tenir compte des deux situations possibles – d'ailleurs, elle devra peut-être changer de nom pour refléter ce changement.
Allez, c'est à vous !
Suivez la solution
Alors vous avez réussi ? Sinon, pas de panique, voici une proposition de solution.
Première étape : le texte du bouton doit devenir dynamique, car il doit changer. On va donc créer une propriété buttonText
et l'initialiser à sa valeur d'origine, puis on va ajouter ce texte au bouton avec la string interpolation. Dans le TypeScript :
snapButtonText!: string;
// ...
this.snapButtonText = 'Oh Snap!';
… et dans le template :
(click)="onAddSnap()"{{ snapButtonText }}
Visuellement, rien n'a changé, mais ça veut dire que vous pouvez maintenant contrôler le texte du bouton !
Deuxième étape : on va ajouter une propriété userHasSnapped
pour savoir si l'utilisateur a déjà snapped l'image
Troisième étape : on doit modifier le comportement de la méthode appelée. Je propose de la renommer onSnap()
et de baser son comportement sur la valeur de userHasSnapped
:
onSnap(): void {
if (this.userHasSnapped) {
this.snaps--;
this.snapButtonText = 'Oh Snap!';
this.userHasSnapped = false;
} else {
this.snaps++;
this.snapButtonText = 'Oops, unSnap!';
this.userHasSnapped = true;
}
}
N'oubliez pas de renommer la méthode dans le template également !
Ça y est ! La fonctionnalité est terminée : vous avez réussi à réagir à un événement venant du template, et à exécuter un comportement conditionnel, tout en vous servant de la string interpolation pour afficher le résultat et pour rendre dynamique le texte du bouton !
En résumé
Pour lier une méthode à un événement d'un élément du template, mettez l'événement entre parenthèses
()
et passez la méthode en argument ; ex. :(click)="onClickButton()"
Dans le prochain et dernier chapitre de cette partie du cours, vous allez ajouter des propriétés personnalisées à vos components pour leur passer des données depuis l'extérieur !