Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Angular

Introduction aux formulaires en angulaire 4: formes réactives

by
Difficulty:BeginnerLength:LongLanguages:
This post is part of a series called Introduction to Forms in Angular 4.
Introduction to Forms in Angular 4: Template-Driven Forms
Introduction to Forms in Angular 4: Writing Custom Form Validators

French (Français) translation by honeymmmm (you can also view the original English article)

Final product image
What You'll Be Creating

Ceci est la deuxième partie de la série sur l'introduction aux formulaires dans Angular 4. Dans la première partie, nous avons créé un formulaire en utilisant l'approche par modèle. Nous avons utilisé des directives telles que ngModel, ngModelGroup et ngForm pour surcharger les éléments de formulaire. Dans ce tutoriel, nous adopterons une approche différente des formes de construction - la méthode réactive.

Formes réactives

Les formes réactives adoptent une approche différente de celle des formulaires basés sur des modèles. Ici, nous créons et initialisons les objets de contrôle de formulaire dans notre classe de composants. Ce sont des objets intermédiaires qui contiennent l'état du formulaire. Nous les lierons ensuite aux éléments de contrôle de formulaire du modèle.

L'objet de contrôle de formulaire écoute toute modification des valeurs de contrôle d'entrée et est immédiatement reflétée dans l'état de l'objet. Comme le composant a un accès direct à la structure du modèle de données, toutes les modifications peuvent être synchronisées entre le modèle de données, l'objet de contrôle de formulaire et les valeurs de contrôle d'entrée.

High level overview of Reactive forms using model-driven approach

En pratique, si nous construisons un formulaire pour mettre à jour le profil utilisateur, le modèle de données est l'objet utilisateur extrait du serveur. Par convention, cela est souvent stocké dans la propriété utilisateur du composant (this.user). L'objet de contrôle de formulaire ou le modèle de formulaire seront liés aux éléments de contrôle de formulaire réels du modèle.

Ces deux modèles doivent avoir des structures similaires, même s’ils ne sont pas identiques. Cependant, les valeurs d'entrée ne doivent pas entrer directement dans le modèle de données. L'image décrit comment l'utilisateur entre le modèle et le modèle de formulaire.

Commençons.

Conditions préalables

Vous n’avez pas besoin de suivre la première partie de cette série, la deuxième partie ayant un sens. Cependant, si vous ne connaissez pas encore les formulaires dans Angular, je vous recommande vivement de passer par la stratégie basée sur des modèles. Le code de ce projet est disponible sur mon référentiel GitHub. Assurez-vous que vous êtes sur la bonne branche, puis téléchargez le fichier zip ou clonez le dépôt pour voir le formulaire en action.

Si vous préférez commencer à partir de zéro, assurez-vous d'avoir installé Angular CLI. Utilisez la commande ngpour générer un nouveau projet.

Ensuite, générez un nouveau composant pour SignupForm ou créez-en un manuellement.

Remplacez le contenu de app.component.html par celui-ci:

Voici la structure du répertoire src /. J'ai supprimé certains fichiers non essentiels pour garder les choses simples.

Comme vous pouvez le voir, un répertoire pour le composant SignupForma été créé automatiquement. C'est là que va la plupart de notre code. J'ai également créé un nouveau User.ts pour stocker notre modèle d'utilisateur.

Le modèle HTML

Avant de nous plonger dans le modèle de composant actuel, nous devons avoir une idée abstraite de ce que nous construisons. Donc, voici la structure de forme que j'ai en tête. Le formulaire d'inscription aura plusieurs champs de saisie, un élément select et un élément checkbox.

The HTML Template

Voici le modèle HTML que nous utiliserons pour notre page d'inscription.

Modèle HTML

Les classes CSS utilisées dans le modèle HTML font partie de la bibliothèque Bootstrap utilisée pour rendre les choses belles. Comme il ne s’agit pas d’un tutoriel de conception, je ne parlerai pas beaucoup des aspects CSS du formulaire, sauf si cela est nécessaire.

Configuration de formulaire de base

Pour créer un formulaire réactif, vous devez importer le ReactiveFormsModuleà partir de @angular/forms et l'ajouter au tableau imports dans app.module.ts.

app/app.module.ts

Ensuite, créez un modèle d'utilisateur pour le formulaire d'inscription. Nous pouvons soit utiliser une classe ou une interface pour créer le modèle. Pour ce tutoriel, je vais exporter une classe avec les propriétés suivantes.

app/User.ts

Maintenant, créez une instance du modèle User dans le composant SignupForm.

app/signup-form/signup-form.component.ts

Pour le fichier signup-form.component.html, je vais utiliser le même modèle HTML que celui décrit ci-dessus, mais avec des modifications mineures. Le formulaire d'inscription comporte un champ de sélection avec une liste d'options. Bien que cela fonctionne, nous le ferons de manière angulaire en parcourant la liste en utilisant la directive ngFor.

app/signup-form/signup-form.component.html

Remarque: Vous pourriez obtenir une erreur indiquant No provider for ControlContainer. L'erreur apparaît lorsqu'un composant a une balise <form> sans directive formGroup. L'erreur disparaîtra lorsque nous ajouterons plus tard une directive FormGroup dans le tutoriel.

Nous avons un composant, un modèle et un modèle de formulaire à portée de main. Et maintenant? Il est temps de vous salir les mains et de vous familiariser avec les API dont vous avez besoin pour créer des formulaires réactifs. Cela inclut FormControl et FormGroup.

Suivi de l'état à l'aide de FormControl

Lors de la création de formulaires avec la stratégie de formulaires réactifs, vous ne rencontrerez pas les directives ngModel et ngForm. Au lieu de cela, nous utilisons l'API FormControl et FormGroup sous-jacente.

Un FormControl est une directive utilisée pour créer une instance de FormControl que vous pouvez utiliser pour suivre l'état d'un élément de formulaire particulier et son état de validation. Voici comment fonctionne FormControl:

email est désormais une instance de FormControl, et vous pouvez le lier à un élément de contrôle d'entrée de votre modèle comme suit:

L'élément de formulaire modèle est désormais lié à l'instance FormControl dans le composant. Ce que cela signifie, c'est que tout changement de la valeur du contrôle d'entrée est répercuté à l'autre extrémité.

Un constructeur FormControl accepte trois arguments: une valeur initiale, un tableau de validateurs de synchronisation et un tableau de validateurs asynchrones. Comme vous l'avez peut-être deviné, ils sont tous facultatifs. Nous allons couvrir les deux premiers arguments ici.

Angular dispose d'un ensemble limité de validateurs intégrés. Les méthodes de validation les plus courantes incluent Validators.required, Validators.minLength, Validators.maxlength et Validators.pattern. Cependant, pour les utiliser, vous devez d'abord importer l'API Validator.

Pour notre formulaire d'inscription, nous avons plusieurs champs de contrôle d'entrée (pour le courrier électronique et le mot de passe), un champ de sélection et un champ de case à cocher. Plutôt que de créer des objets FormControl individuels, ne serait-il pas plus logique de regrouper tous ces contrôles FormControls sous une seule entité? Cela est bénéfique car nous pouvons désormais suivre la valeur et la validité de tous les objets sous-FormControl à un seul endroit. C'est ce que FormGroup est pour. Nous allons donc enregistrer un FormGroup parent avec plusieurs FormControls enfants.

Grouper plusieurs contrôles de formulaire avec FormGroup

Pour ajouter un FormGroup, importez-le d'abord. Ensuite, déclarez signupForm comme une propriété de classe et initialisez-la comme suit:

app/signup-form/signup-form.component.ts

Liez le modèle FormGroup au DOM comme suit:

app/signup-form/signup-form.component.html

[formGroup] = "signupForm" indique à Angular que vous souhaitez associer ce formulaire au FormGroup déclaré dans la classe du composant. Lorsque Angular voit formControlName = "email", il recherche une instance de FormControl avec la valeur de clé email dans le groupe FormGroup.

De même, mettez à jour les autres éléments du formulaire en ajoutant un attribut formControlName="value" comme nous venons de le faire.

Pour voir si tout fonctionne comme prévu, ajoutez ce qui suit après la balise de formulaire:

app/signup-form/signup-form.component.html

Placez la propriété SignupForm dans le JsonPipe pour rendre le modèle en tant que JSON dans le navigateur. Ceci est utile pour le débogage et la journalisation. Vous devriez voir une sortie JSON comme celle-ci.

Form state and validty in Model-driven forms

Il y a deux choses à noter ici:

  1. Le JSON ne correspond pas exactement à la structure du modèle utilisateur que nous avons créé précédemment.
  2. Le signupForm.status affiche que le statut du formulaire est INVALID. Cela montre clairement que le fichier Validators.required sur le champ de contrôle du courrier électronique fonctionne comme prévu.

La structure du modèle de formulaire et du modèle de données doit correspondre.

Pour obtenir la structure hiérarchique du modèle de données, nous devons utiliser un groupe de formulaires imbriqué. De plus, il est toujours conseillé d’avoir des éléments de formulaire associés sous un seul groupe de formulaires.

Nested FormGroup

Créez un nouveau groupe de formulaires pour le mot de passe.

app/signup-form/signup-form.component.ts

Maintenant, pour lier le nouveau modèle de formulaire au DOM, apportez les modifications suivantes:

app/signup-form/signup-form.component.html

formGroupName = "password" effectue la liaison pour le FormGroup imbriqué. Maintenant, la structure du modèle de formulaire correspond à nos exigences.

Ensuite, nous devons valider les contrôles de formulaire.

Valider le formulaire

Nous avons une simple validation en place pour le contrôle de saisie par courrier électronique. Cependant, ce n'est pas suffisant. Voici la liste complète de nos exigences pour la validation.

  • Tous les éléments de contrôle de formulaire sont requis.
  • Désactivez le bouton d'envoi jusqu'à ce que le statut du formulaire soit VALID.
  • Le champ email doit contenir strictement un identifiant email.
  • Le champ mot de passe doit avoir une longueur minimale de 8.
Validating the form

Le premier est facile. Ajoutez Validator.required à tous les FormControls du modèle de formulaire.

app/signup-form/signup-form.component.ts

Ensuite, désactivez le bouton lorsque le formulaire est INVALID.

app/signup-form/signup-form.component.html

Pour ajouter une contrainte sur le courrier électronique, vous pouvez utiliser le fichier Validators.email par défaut ou créer un fichier Validators.pattern() personnalisé qui spécifie des expressions régulières telles que celle ci-dessous:

Utilisez le validateur minLength pour les champs de mot de passe.

C'est ça pour la validation. Cependant, la logique du modèle de formulaire semble encombrée et répétitive. Nettoyons cela en premier.

Refactoring du code à l'aide de FormBuilder

Angular vous fournit un sucre de syntaxe pour créer de nouvelles instances de FormGroup et FormControl appelées FormBuilder. L'API FormBuilder ne fait rien d'autre que ce que nous avons traité ici.

Cela simplifie notre code et facilite la création d'un formulaire. Pour créer un FormBuilder, vous devez l'importer dans signup-form.component.ts et injecter le FormBuilder dans le constructeur.

app/signup-form/signup-form.component.ts

Au lieu de créer un nouveau FormGroup (), nous utilisons this.fb.group pour créer un formulaire. Sauf pour la syntaxe, tout le reste reste le même.

app/signup-form/signup-form.component.ts

Affichage des erreurs de validation

Pour afficher les erreurs, je vais utiliser la directive conditionnelle ngIf sur un élément div. Commençons par le champ de contrôle d'entrée pour l'email:

Il y a quelques problèmes ici.

  1. D'où venaient invalid et pristine?
  2. signupForm.controls.email.invalid est trop long et trop profond.
  3. L'erreur ne dit pas explicitement pourquoi elle est invalide.

Pour répondre à la première question, chaque FormControl a certaines propriétés comme invalid, valid, pristine, dirty, touched et untouched. Nous pouvons les utiliser pour déterminer si un message d'erreur ou un avertissement doit être affiché ou non. L'image ci-dessous décrit chacune de ces propriétés en détail.

 FormControl Properties in Angular Reactive approach

Donc, l'élément div avec le *ngIf sera rendu uniquement si l'email est invalide. Cependant, l'utilisateur sera accueilli avec des erreurs concernant les champs de saisie vides avant même qu'ils aient la possibilité de modifier le formulaire.

Pour éviter ce scénario, nous avons ajouté la deuxième condition. L'erreur sera affichée uniquement après la visite du contrôle.

Pour me débarrasser de la longue chaîne de noms de méthodes (signupForm.controls.email.invalid), je vais ajouter quelques méthodes de raccourcis. Cela les garde plus accessibles et courts.

app/signup-form/signup-form.component.ts

Pour rendre l'erreur plus explicite, j'ai ajouté les conditions ngIf imbriquées ci-dessous:

app/signup-form/signup-form.component.html

Nous utilisons email.errors pour vérifier toutes les erreurs de validation possibles, puis les afficher sous la forme de messages personnalisés. Suivez maintenant la même procédure pour les autres éléments de formulaire. Voici comment j'ai codé la validation pour les mots de passe et les termes du contrôle d'entrée.

app/signup-form/signup-form.component.html

Soumettre le formulaire en utilisant ngSubmit

Nous avons presque fini avec le formulaire. Il manque la fonctionnalité de soumission que nous sommes sur le point de mettre en œuvre maintenant.

Sur la soumission de formulaire, les valeurs du modèle de formulaire doivent se trouver dans la propriété utilisateur du composant.

app/signup-form/signup-form.component.ts

Démo finale

Voici la version finale de l'application. J'ai ajouté quelques classes Bootstrap pour rendre la forme jolie.

L'envelopper

Si vous avez suivi cette série de didacticiels depuis le début, nous avons eu une expérience pratique avec deux technologies de création de formulaires populaires dans Angular. Les techniques basées sur des modèles et sur des modèles sont deux manières de réaliser la même chose. Personnellement, je préfère utiliser les formulaires réactifs pour les raisons suivantes:

  • Toute la logique de validation de formulaire sera située dans un seul endroit, à l'intérieur de votre classe de composant. C'est beaucoup plus productif que l'approche par modèle, où les directives ngModel sont dispersées dans le modèle.
  • Contrairement aux formulaires pilotés par un modèle, les formulaires pilotés par un modèle sont plus faciles à tester. Vous n'avez pas à recourir à des bibliothèques de test de bout en bout pour tester votre formulaire.
  • La logique de validation ira dans la classe du composant et non dans le modèle.
  • Pour une forme contenant un grand nombre d'éléments de formulaire, cette approche s'appelle FormBuilder pour faciliter la création d'objets FormControl.

Nous avons manqué une chose, et c'est écrire un validateur pour la non-concordance du mot de passe. Dans la dernière partie de la série, nous couvrirons tout ce que vous devez savoir sur la création de fonctions de validation personnalisées dans Angular. Restez à l'écoute jusque-là.

En attendant, il existe de nombreux frameworks et bibliothèques pour vous occuper, avec de nombreux éléments sur Envato Market à lire, à étudier et à utiliser.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.