Dans énormément d'applications web, une fonctionnalité essentielle est d'accepter de l'entrée utilisateur, généralement sous la forme de formulaires.
En Angular, il existe deux méthodes pour créer des formulaires : celle dite "template" et celle dite "réactive". Depuis un an ou deux (au moment de l'écriture de ce cours), les formulaires réactifs ont pris le dessus. Ils sont un peu plus longs à créer mais ils permettent beaucoup plus de possibilités, comme vous le verrez au chapitre suivant.
Dans ce chapitre, vous découvrirez les formulaires template. Même s'ils sont moins puissants que leurs cousins réactifs, ils sont utilisés dans beaucoup de cas où un formulaire simple suffit.
Regardons dès maintenant comment créer et exploiter un formulaire template pour permettre aux utilisateurs de Snapface de s'inscrire pour la newsletter.
Importez FormsModule
Avant toute chose, si ce n'est pas déjà le cas dans votre application, il faut ajouter FormsModule
(importé depuis @angular/forms
) aux imports
de votre AppModule :
// ...
imports: [
BrowserModule,
AppRoutingModule,
FormsModule
],
//...
Générez un formulaire avec du HTML
Comme il s'agit de la méthode template, commençons par ajouter au template, landing-page.component.html
:
<form>
<label for="emailInput">Inscrivez-vous pour recevoir notre newsletter !</label>
<input type="email" id="emailInput">
<button type="submit">OK!</button>
</form>
Jusqu'ici, rien de bien magique : c'est un formulaire tout à fait classique.
Préparez le fichier TypeScript du component en y créant une variable userEmail
qui contiendra la valeur entrée par l'utilisateur, ainsi qu'une méthode onSubmit()
pour l'envoi du formulaire :
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-landing-page',
templateUrl: './landing-page.component.html',
styleUrls: ['./landing-page.component.scss']
})
export class LandingPageComponent implements OnInit {
userEmail: string;
constructor(private router: Router) { }
ngOnInit(): void {
}
onContinue(): void {
this.router.navigateByUrl('facesnaps');
}
onSubmitForm() {
console.log(this.userEmail);
}
}
Comme vous pouvez le constater, la variable userEmail
est une string
normale. Pour la lier à la valeur de la balise <input>
, vous allez utiliser une nouvelle directive – ngModel
:
<input id="emailInput" name="userEmail" type="email" [(ngModel)]="userEmail">
Alors, vous savez que l'attribute binding se passe avec les crochets []
, et l'event binding avec les parenthèses ()
, mais là vous avez les deux en même temps ! Du coup, on trouve ce qui s'appelle le two-way binding, ou la liaison à double sens.
Mais qu'est-ce que ça fait ?
Le two-way binding lie totalement la valeur de la variable à la valeur du <input>
. Si vous y attribuez une valeur depuis le TypeScript :
userEmail = 'me@my-house.com';
... dans le DOM :
... pour la liaison dans l'autre sens, il faut lier le bouton du formulaire à la méthode onSubmit
. Vous pouvez utiliser l'event binding avec (click)
, mais il y a une autre approche pour les formulaires. Dans la balise <form>
:
<form (ngSubmit)="onSubmitForm()">
Modifiez l'adresse mail dans l'input, et cliquez sur le bouton :
Dans la console :
Visiblement, le two-way binding relie complètement la valeur de la variable à la valeur de l'input !
Captez le formulaire entier
Si votre formulaire commence à acquérir des champs supplémentaires, ça deviendra vite lourd et difficile à maintenir de récupérer systématiquement les valeurs de toutes les variables liées aux champs. Heureusement, Angular a pensé à vous !
Le système de formulaires template vous permet de passer le formulaire complet en argument comme NgForm
. Modifiez d'abord l'empreinte de onSubmitForm()
pour accepter le formulaire comme argument :
onSubmitForm(form: NgForm) {
console.log(form.value);
}
Le type NgForm
expose un attribut value
qui correspond à un objet contenant les champs du formulaire avec leur attribut name
et les valeurs contenues dans ces champs.
Pour récupérer le NgForm
correspondant à votre formulaire, vous allez utiliser une référence locale :
<form #emailForm="ngForm" (ngSubmit)="onSubmitForm(emailForm)">
Une référence locale, créée avec un dièse #
comme ci-dessus, permet à Angular d'accéder à l'élément pour, par exemple, l'envoyer comme argument à une méthode comme vous le faites ici.
Maintenant, si vous cliquez sur OK!
:
Et voilà ! Vous savez maintenant utiliser les formulaires template pour demander des informations simples à vos utilisateurs.
Dans ce cas précis, vous affichez simplement la valeur reçue dans la console, mais on peut très bien imaginer appeler une méthode de service pour transmettre cette valeur au serveur.
En résumé
Ajoutez FormsModule aux
imports
de votre AppModule pour débloquer les formulaires template ;Utilisez le two-way binding avec
[(ngModel)]
pour lier une variable au contenu d'uninput
;Liez votre méthode d'envoi de formulaire au bouton de type
submit
avec l'événementngSubmit
;Envoyez le formulaire en entier avec une référence locale à la directive
ngForm
et une méthode qui attend un argument de typeNgForm
– n'oubliez pas d'ajouter des attributsname
à tous vosinput
!
Suivez-moi au chapitre suivant pour découvrir les formulaires réactifs et tout ce que nous pouvons faire avec eux !