Introduction aux formulaires angulaires 4 formulaires basés sur des modèles

Ce que vous allez créer

Les formulaires sont essentiels à toute application frontale moderne et ils constituent une fonctionnalité que nous utilisons tous les jours, même si nous ne le réalisons pas. Des formulaires sont nécessaires pour connecter en toute sécurité un utilisateur à l'application, rechercher tous les hôtels disponibles dans une ville donnée, réserver un taxi, créer une liste de tâches et faire des tonnes de choses que nous avons l'habitude de faire. Certains formulaires ne comportent que quelques champs de saisie, tandis que d’autres peuvent comporter un tableau de champs pouvant s’étendre sur quelques pages ou onglets.. 

Dans ce tutoriel, nous parlerons de différentes stratégies disponibles pour développer des formes en angulaire. Indépendamment de la stratégie que vous choisissez, voici les éléments qu'une bibliothèque de formulaires devrait couvrir:

  • Prise en charge de la liaison bidirectionnelle afin que les valeurs de contrôle d'entrée soient synchronisées avec l'état du composant.
  • Gardez une trace de l'état du formulaire et utilisez des indices visuels pour indiquer à l'utilisateur si l'état actuel est valide ou non. Par exemple, si le nom d'utilisateur comporte des caractères non valides, une bordure rouge doit apparaître autour du champ de saisie du nom d'utilisateur..
  • Avoir un mécanisme pour afficher correctement les erreurs de validation.
  • Activer ou désactiver certaines parties du formulaire sauf si certains critères de validation sont remplis.

Introduction aux formes angulaires

Angular, en tant que framework frontal complet, dispose de son propre ensemble de bibliothèques pour la création de formulaires complexes. La dernière version de Angular propose deux stratégies puissantes de création de formulaires. Elles sont:

  • formulaires basés sur des modèles 
  • formes dirigées par les modèles ou réactives

Les deux technologies appartiennent à la @ angulaire / formes bibliothèque et sont basés sur les mêmes classes de contrôle de formulaire. Cependant, ils diffèrent remarquablement par leur philosophie, leur style de programmation et leur technique. Le choix de l'un sur l'autre dépend de vos goûts personnels et de la complexité de la forme que vous essayez de créer. À mon avis, vous devriez d'abord essayer les deux approches, puis choisir celle qui correspond à votre style et au projet en cours.. 

La première partie du didacticiel couvrira les formulaires pilotés par des modèles avec un exemple pratique: la création d’un formulaire d’inscription avec validation pour tous les champs de formulaire. Dans la deuxième partie de ce didacticiel, nous allons retracer les étapes pour créer le même formulaire en utilisant une approche basée sur un modèle.. 

Formulaires basés sur des modèles

L’approche basée sur des modèles est une stratégie empruntée à l’ère AngularJS. À mon avis, c'est la méthode la plus simple pour créer des formes. Comment ça marche? Nous allons utiliser des directives angulaires. 

Les directives vous permettent d'attacher un comportement aux éléments du DOM.
- Documentation angulaire

Angular fournit des directives spécifiques au formulaire que vous pouvez utiliser pour lier les données d'entrée de formulaire et le modèle. Les directives spécifiques à un formulaire ajoutent des fonctionnalités et un comportement supplémentaires à un formulaire HTML simple. Le résultat final est que le modèle prend en charge les valeurs de liaison avec le modèle et la validation du formulaire. 

Dans ce tutoriel, nous allons utiliser des formulaires basés sur des modèles pour créer la page d'inscription d'une application. Le formulaire couvrira les éléments de formulaire les plus courants et différents contrôles de validation sur ces éléments de formulaire. Voici les étapes à suivre dans ce tutoriel.

  • Ajouter FormsModule à app.module.ts.
  • Créer une classe pour le modèle utilisateur.
  • Créer les composants initiaux et la mise en page pour le formulaire d'inscription.
  • Utilisez des directives de forme angulaire comme ngModelngModelGroup, et ngForm.
  • Ajouter une validation à l'aide de validateurs intégrés.
  • Afficher les erreurs de validation de manière significative.
  • Traiter la soumission du formulaire en utilisant ngSubmit.

Commençons.

Conditions préalables

Le code de ce projet est disponible sur mon dépôt GitHub. Téléchargez le zip ou clonez le référentiel pour le voir en action. Si vous préférez commencer à partir de zéro, assurez-vous d’avoir installé Angular CLI. Utilisez le ng commande pour générer un nouveau projet. 

$ ng new SignupFormProject

Ensuite, générez un nouveau composant pour le SignupForm.

ng générer le composant SignupForm

Remplacer le contenu de app.component.html avec ça:

 

Voici la structure de répertoire pour le src / annuaire. J'ai supprimé des fichiers non essentiels pour que tout reste simple.

. ├── app │ ├── app.component.css app.component.html app.component.ts app.module.ts le formulaire d'inscription │ ├ ── signup-form.component.css ├── signup-form.component.html ts signup-form.component.ts └── User.ts ├── index.html main .ts ├── polyfills.ts ├── styles.css ├── tsconfig.app.json typings.d.ts 

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

Le modèle HTML

Avant de plonger dans le modèle de composant réel, nous devons avoir une idée abstraite de ce que nous construisons. Donc, voici la structure de forme que j'ai dans mon esprit. Le formulaire d'inscription comportera plusieurs champs de saisie, un élément de sélection et un élément de case à cocher.. 


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

Modèle HTML

 
S'inscrire

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

Configuration de base du formulaire

Pour utiliser les directives de formulaire gérées par des modèles, nous devons importer le FormsModule de @ angulaire / formes et l'ajouter à la importations tableau dans app.module.ts.

app / app.module.ts

importer FormsModule à partir de '@ angular / forms'; @NgModule (… importations: [BrowserModule, FormsModule],…) classe d'exportation AppModule  

Ensuite, créez une classe qui contiendra toutes les propriétés de l'entité User. Nous pouvons soit utiliser une interface et l'implémenter dans le composant, soit utiliser une classe TypeScript pour le modèle..

app / User.ts

classe d'exportation User id: number; email: chaîne; // Les deux mots de passe sont dans un seul objet mot de passe: pwd: string; confirmPwd: string; ; sexe: chaîne; termes: booléen; constructeur (valeurs: Object = ) // Initialisation du constructeur Object.assign (this, values);  

Créez maintenant une instance de la classe dans le composant SignupForm. J'ai également déclaré une propriété supplémentaire pour le genre. 

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

importer Component, OnInit à partir de '@ angular / core'; // Importe le modèle utilisateur import User depuis './… / User'; @Component (sélecteur: 'app-signup-form', templateUrl: './signup-form.component.html', styleUrls: ['./signup-form.component.css']) La classe d'exportation SignupFormComponent implémente OnInit // Propriété pour le genre privé genre: string []; // Propriété pour l'utilisateur utilisateur privé: User; ngOnInit () this.gender = ['Homme', 'Femme', 'Autres']; // Créer un nouvel objet utilisateur this.user = nouvel utilisateur (email: "", mot de passe: pwd: "", confirm_pwd: "", genre: this.gender [0], terms: false);  

Pour le signup-form.component.html fichier, je vais utiliser le même modèle HTML discuté 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 à l’aide des touches ngFor directif.

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

S'inscrire

Ensuite, nous souhaitons lier les données de formulaire à l’objet classe d’utilisateurs de sorte que, lorsque vous saisissez les données d’inscription dans le formulaire, un nouvel objet Utilisateur soit créé pour stocker temporairement ces données. De cette façon, vous pouvez maintenir la synchronisation de la vue avec le modèle. Cette opération est appelée liaison.. 

Il y a plusieurs façons d'y arriver. Laissez-moi d'abord vous présenter ngModel et ngForm.

ngForm et ngModel

ngForm et ngModel sont des directives angulaires essentielles à la création de formulaires gérés par des modèles. Commençons avec ngForm premier. Voici un extrait sur ngForm de la documentation angulaire.

le NgForm directive complète le forme élément avec des fonctionnalités supplémentaires. Il contient les contrôles que vous avez créés pour les éléments avec un ngModel directive et prénom attribut, et surveille leurs propriétés, y compris leur validité. Il a aussi son propre valide propriété qui est vraie seulement si chaque contrôle contenu est valable.

Tout d'abord, mettez à jour le formulaire avec le ngForm directif:

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

#signupForm est une variable de référence de modèle qui fait référence à la ngForm directive qui régit l’ensemble du formulaire. L'exemple ci-dessous illustre l'utilisation d'un ngForm objet de référence pour validation.

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

Ici, signupForm.form.valid retournera false si tous les éléments du formulaire ne réussissent pas leurs contrôles de validation respectifs. Le bouton d'envoi sera désactivé jusqu'à ce que le formulaire soit valide.  

En ce qui concerne la liaison du modèle et du modèle, il existe de nombreuses façons de le faire, et ngModel a trois syntaxes différentes pour faire face à cette situation. Elles sont:

  1. [(ngModel)] 
  2. [ngModel]
  3. ngModel

Commençons par le premier.

Liaison bidirectionnelle à l'aide de [(ngModel)]

[(ngModel)] effectue une liaison bidirectionnelle pour la lecture et l'écriture des valeurs de contrôle d'entrée. Si un [(ngModel)] Si la directive est utilisée, le champ de saisie prend une valeur initiale de la classe de composants liés et la remet à jour chaque fois que toute modification de la valeur de contrôle de saisie est détectée (sur une frappe au clavier ou sur une touche). L'image ci-dessous décrit mieux le processus de liaison bidirectionnelle.

Voici le code du champ de saisie du courrier électronique:

 

[(ngModel)] = "user.email" lie la propriété email de l'utilisateur à la valeur d'entrée. J'ai aussi ajouté un prénom attribuer et définir name = "email". Ceci est important et vous obtiendrez une erreur si vous n'avez pas déclaré d'attribut name lorsque vous utilisez ngModel.. 

De même, ajoutez un [(ngModel)] et unique prénom attribut à chaque élément de formulaire. Votre formulaire devrait ressembler à quelque chose comme ça maintenant:

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

le ngModelGroup est utilisé pour regrouper des champs de formulaire similaires afin que nous puissions exécuter des validations uniquement sur ces champs de formulaire. Étant donné que les deux champs de mot de passe sont liés, nous les placerons sous un seul groupe ngModelGroup. Si tout fonctionne comme prévu, le composant lié utilisateur Cette propriété doit être chargée de stocker toutes les valeurs de contrôle de formulaire. Pour voir cela en action, ajoutez ce qui suit après la balise de formulaire:

utilisateur | json

Dirigez la propriété de l'utilisateur à travers le JsonPipe rendre le modèle au format JSON dans le navigateur. Ceci est utile pour le débogage et la journalisation. Vous devriez voir une sortie JSON comme celle-ci. 

Les valeurs vont de la vue au modèle. Qu'en est-il de l'inverse? Essayez d'initialiser l'objet utilisateur avec des valeurs.

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

this.user = nouvel utilisateur (// initialisé avec un courrier électronique de données: "[email protected]", mot de passe: pwd: "", confirm_pwd: "", genre: this.gender [0]);

Et ils apparaissent automatiquement dans la vue:

"email": "[email protected]", "mot de passe": "pwd": "", "confirm_pwd": "", "genre": "Homme"

La liaison à double sens [(ngModel)] La syntaxe vous aide à créer des formulaires sans effort. Cependant, il présente certains inconvénients. par conséquent, il existe une approche alternative qui utilise ngModel ou [ngModel].

Ajout de ngModel au mélange

Quand ngModel est utilisé, nous sommes en fait responsables de la mise à jour de la propriété du composant avec les valeurs de contrôle en entrée et inversement. Les données d'entrée ne sont pas automatiquement transférées dans la propriété utilisateur du composant..

Alors remplacez toutes les instances de [(ngModel)] = "" avec ngModel. Nous garderons le prénom attribut parce que les trois versions de ngModel ont besoin du prénom attribuer au travail. 

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

Avec ngModel, la valeur de l'attribut name deviendra une clé de l'objet de référence ngForm SignupForm que nous avons créé plus tôt. Donc, par exemple, signupForm.value.email va stocker la valeur de contrôle pour l'id email. 

Remplacer utilisateur | json avec signupForm.value | json parce que c'est là que tout l'état est stocké en ce moment. 

Liaison unidirectionnelle à l'aide de [ngModel]

Que faire si vous devez définir l'état initial à partir du composant de classe liée? C'est ce que le [ngModel] fait pour vous. 

Ici, les données circulent du modèle à la vue. Apportez les modifications suivantes à la syntaxe pour utiliser la liaison unidirectionnelle:

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

Alors, quelle approche devriez-vous choisir? Si vous utilisez [(ngModel)] et ngForm ensemble, vous aurez éventuellement deux états à maintenir-utilisateur et signupForm.value-et cela pourrait être potentiellement déroutant. 

"email": "[email protected]", "mot de passe": "pwd": "thisispassword", "confirm_pwd": "thisispassword", "genre": "Homme" //user.value " email ":" [email protected] "," password ": " pwd ":" thisispassword "," confirm_pwd ":" thisispassword "," gender ":" Homme " //signupForm.value 

Par conséquent, je recommanderai plutôt l’utilisation de la méthode de liaison à sens unique. Mais c'est quelque chose à vous de décider.

Validation et affichage des messages d'erreur 

Voici nos exigences pour la validation.

  • Tous les contrôles de formulaire sont Champs obligatoires.
  • Désactiver le bouton d'envoi jusqu'à ce que tous les champs de saisie soient remplis.
  • Le champ email doit contenir strictement un identifiant.
  • Le mot de passe doit avoir une longueur minimale de 8.
  • Le mot de passe et la confirmation doivent correspondre.
Notre formulaire avec validation en place

Le premier est facile. Vous devez ajouter un Champs obligatoires attribut de validation pour chaque élément de formulaire comme ceci:

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

Séparé de Champs obligatoires attribut, j'ai aussi exporté un nouveau #email variable de référence du modèle. Cela vous permet d'accéder au contrôle angulaire de la zone de saisie à partir du modèle même. Nous allons l'utiliser pour afficher des erreurs et des avertissements. Maintenant, utilisez la propriété disabled du bouton pour le désactiver:

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

Pour ajouter une contrainte sur le courrier électronique, utilisez l'attribut de modèle qui fonctionne avec les champs de saisie. Les modèles sont utilisés pour spécifier des expressions régulières comme celle ci-dessous:

pattern = "[a-z0-9 ._% + -] + @ [a-z0-9 .-] + \. [a-z] 2,3 $"

Pour le champ mot de passe, tout ce que vous avez à faire est d’ajouter un minlength = "" attribut:

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

 

Pour afficher les erreurs, je vais utiliser la directive conditionnelle ngIf sur un élément div. Commençons par le champ de contrôle de saisie pour le courrier électronique:

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

Le champ email ne peut pas être vide
L'identifiant email ne semble pas correct

Il y a beaucoup de choses ici. Commençons par la première ligne de la section d'erreur.

Se souvenir du #email variable que nous avons exportée plus tôt? Il contient une quantité d'informations sur l'état de contrôle de saisie du champ de courrier électronique. Ceci comprend: email.valide, email.invalide, email.dirty, email.pristine, email.touched, email.touche, et email.errors.  L'image ci-dessous décrit chacune de ces propriétés en détail.

Donc, l'élément div avec le * ngIf sera rendu que si l'email est invalide. Cependant, l'utilisateur sera accueilli avec des erreurs sur le fait que les champs de saisie sont vides avant même d'avoir la possibilité de modifier le formulaire.. 

Pour éviter ce scénario, nous avons ajouté la deuxième condition. L'erreur ne sera affichée qu'après le contrôle a été visité ou la valeur du contrôle a été changée.

Les éléments div imbriqués sont utilisés pour couvrir tous les cas d'erreurs de validation. Nous utilisons email.errors pour vérifier toutes les erreurs de validation possibles puis les réafficher à l'utilisateur sous 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 des mots de passe. 

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

 
Le mot de passe doit comporter plus de 8 caractères.
Les mots de passe ne correspondent pas

Cela commence à avoir l'air un peu brouillon. Angular a un ensemble limité d'attributs de validateur: Champs obligatoires, Longueur minimale, longueur maximale, et modèle. Pour couvrir tout autre scénario tel que celui de la comparaison de mot de passe, vous devrez compter sur ngIf conditionnels comme je l'ai fait ci-dessus. Ou idéalement, créez une fonction de validation personnalisée, que je couvrirai dans la troisième partie de cette série.

Dans le code ci-dessus, j'ai utilisé le ngSi d'autre syntaxe introduite dans la dernière version de Angular. Voici comment cela fonctionne:

Contenu valide…
Contenu non valide…

Soumettez le formulaire en utilisant ngSubmit

Nous avons presque fini le formulaire. Maintenant, nous devons être en mesure de soumettre le formulaire et le contrôle des données du formulaire doit être confié à une méthode composant, par exemple. onFormSubmit ().

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

Maintenant, pour le composant:

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

… Public onFormSubmit (valeur, valide: valeur: Utilisateur, valide: booléen) this.user = valeur; console.log (this.user); console.log ("valide:" + valide); … 

Démo finale

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

Résumé

Nous avons tous fini ici. Dans ce didacticiel, nous avons abordé tout ce que vous devez savoir sur la création d’un formulaire dans Angular à l’aide de l’approche basée sur des modèles. Les formulaires basés sur des modèles sont populaires pour leur simplicité et leur facilité d'utilisation. 

Toutefois, si vous devez créer un formulaire avec de nombreux éléments, cette approche deviendra désordonnée. Donc, dans le prochain tutoriel, nous aborderons le moyen de créer le même formulaire. 

Partagez votre opinion dans les commentaires ci-dessous.

Apprendre JavaScript: le guide complet

Nous avons créé un guide complet pour vous aider à apprendre le JavaScript, que vous soyez débutant en tant que développeur Web ou que vous souhaitiez explorer des sujets plus avancés..