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:
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:
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..
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.
app.module.ts
.ngModel
, ngModelGroup
, et ngForm
.ngSubmit
.Commençons.
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.
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.
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.
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
.
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..
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.
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.
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 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.
leNgForm
directive complète leforme
élément avec des fonctionnalités supplémentaires. Il contient les contrôles que vous avez créés pour les éléments avec unngModel
directive etprénom
attribut, et surveille leurs propriétés, y compris leur validité. Il a aussi son proprevalide
propriété qui est vraie seulement si chaque contrôle contenu est valable.
Tout d'abord, mettez à jour le formulaire avec le ngForm
directif:
#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.
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:
Commençons par le premier.
[(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:
……
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.
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]
.
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.
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.
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:
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.
Voici nos exigences pour la validation.
Le premier est facile. Vous devez ajouter un Champs obligatoires
attribut de validation pour chaque élément de formulaire comme ceci:
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:
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:
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:
Le champ email ne peut pas être videL'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.valide
,email.invalide
,email.dirty
,email.pristine
,email.touched
,email.touche
, etemail.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
, etmodèle
. Pour couvrir tout autre scénario tel que celui de la comparaison de mot de passe, vous devrez compter surngIf
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