Ceci est la troisième partie de la série sur la création de formes en angulaire. Dans les deux premiers tutoriels, nous avons utilisé l'approche de création de formulaires basée sur les modèles et basée sur Angular. Cependant, tout en détaillant les deux approches, il y avait quelque chose que nous n'avons pas couvert: les fonctions de validation personnalisées. Ce tutoriel couvrira tout ce que vous devez savoir sur la rédaction de validateurs personnalisés qui répondent à vos besoins..
Vous n'avez pas besoin de suivre la première ou la deuxième partie de cette série pour que la troisième partie ait un sens. Cependant, si vous êtes tout à fait novice dans Angular, rendez-vous au premier tutoriel de cette série et recommencez.
Sinon, récupérez une copie de ce code dans notre dépôt GitHub et utilisez-la comme point de départ..
Angular ne dispose pas d'une énorme bibliothèque de validateurs intégrée. Depuis Angular 4, nous avons les validateurs populaires suivants dans Angular:
Il y en a un peu plus, et vous pouvez voir la liste complète dans la documentation angulaire.
Nous pouvons utiliser les validateurs intégrés ci-dessus de deux manières:
1. En tant que directives dans des formulaires basés sur des modèles.
2. En tant que validateurs à l’intérieur du FormControl
constructeur sous forme de modèles.
name = new FormControl (", Validators.required)
Si la syntaxe ci-dessus n'a pas de sens, suivez mes tutoriels précédents sur la création d'un formulaire d'inscription à l'aide d'une approche basée sur des modèles ou d'une approche basée sur un modèle, puis passez à l'étape suivante.!
Les validateurs de formulaire intégrés couvrent à peine tous les cas d'utilisation de validation pouvant être requis dans une application réelle. Par exemple, un formulaire d'inscription pourrait devoir vérifier si les valeurs du mot de passe et confirmer les champs de contrôle du mot de passe sont égaux et afficher un message d'erreur s'ils ne correspondent pas. Un validateur qui liste des courriels d’un domaine particulier est un autre exemple courant..
Voici un fait: les formulaires basés sur des modèles ne sont que des formulaires basés sur des modèles situés en dessous. Dans un formulaire basé sur un modèle, nous laissons le modèle se charger de la création du modèle. La question évidente est maintenant, comment attacher un validateur à un formulaire?
Les validateurs ne sont que des fonctions. Dans un formulaire basé sur un modèle, attacher des validateurs à FormControl est simple. Dans un formulaire basé sur des modèles, cependant, il reste un peu de travail à faire. En plus de la fonction validateur, vous devrez écrire une directive pour le validateur et créer des instances de la directive dans le modèle..
Bien que cela ait déjà été couvert, nous allons récapituler rapidement le code du formulaire d'inscription. Tout d'abord, voici l'approche réactive.
// Utilisez le formbuilder pour construire le modèle de formulaire this.signupForm = this.fb.group (email: [", [Validators.required, Validators.pattern ('a-z0-9 ._% + -] + @ [a-z0-9 .-] + \. [az] 2,3 $ ')], mot de passe: this.fb.group (pwd: [", [Validators.required, Validators.minLength (8 )]], confirmPwd: [", [Validators.required, Validators.minLength (8)]], validator: PasswordMatch), genre: [", Validators.required],)
FormBuilder
est un sucre de syntaxe qui crée le FormGroup
et FormControl
les instances. UNE FormControl
suit la valeur et l'état de validation d'un élément de formulaire individuel. UNE FormGroup
, d'autre part, comprend un groupe de FormControl
instances, et il suit la valeur et la validité de l'ensemble du groupe.
Voici la structure que nous avons suivie:
FormGroup -> 'signupForm' FormControl -> 'email' FormGroup -> 'mot de passe' FormControl -> 'pwd' FormControl -> 'confirmPwd' FormControl -> 'genre'
Selon les besoins, nous pouvons attacher un validateur à un FormControl
ou un FormGroup
. Un validateur de liste noire d’e-mail exigerait qu’il soit attaché au FormControl
exemple de l'email.
Cependant, pour les validations plus complexes où plusieurs champs de contrôle doivent être comparés et validés, il est préférable d'ajouter la logique de validation au parent. FormGroup
. Comme vous pouvez le voir, mot de passe
a un FormGroup
son propre, et cela nous permet d'écrire facilement des validateurs qui vérifient l'égalité des pwd
et confirmPwd
.
Pour le formulaire piloté par les modèles, toute cette logique est intégrée au modèle HTML. Voici un exemple:
ngModel
crée une instance de FormControl
et le lie à un élément de contrôle de formulaire. De même, ngModelGroup
crée et lie un FormGroup
exemple à un élément DOM. Ils partagent la même structure de domaine modèle discutée ci-dessus.
Il est également intéressant de noter que FormControl
, FormGroup
, et FormArray
étendre le AbstractControl
classe. Cela signifie que le AbstractControl
La classe est responsable du suivi des valeurs des objets de formulaire, de leur validation et de l'activation d'autres méthodes telles que les méthodes vierges, sales et touchées..
Maintenant que nous connaissons les deux techniques de formulaire, écrivons notre premier validateur personnalisé.
Les validateurs sont des fonctions qui prennent une FormControl
/FormGroup
par exemple en entrée et retour soit nul
ou un objet d'erreur. nul
est renvoyé lorsque la validation est réussie et sinon, l'objet d'erreur est renvoyé. Voici une version très basique d'une fonction de validation.
import FormGroup from '@ angular / forms'; fonction d'exportation passwordMatch (control: FormGroup): [key: string]: boolean
J'ai déclaré une fonction qui accepte une instance de FormGroup
en tant qu'entrée. Il renvoie un objet avec une clé de type chaîne et une valeur true / false. C'est pour que nous puissions retourner un objet d'erreur du formulaire ci-dessous:
mismatch: true
Ensuite, nous devons obtenir la valeur de la pwd
et confirmPwd
Instances de FormControl. Je vais utiliser control.get ()
chercher leurs valeurs.
fonction d'exportation passwordMatch (control: FormGroup): [clé: chaîne de caractères]: boolean // Grab pwd et confirmPwd à l'aide de control.get const pwd = control.get ('pwd'); const confirmPwd = control.get ('confirmPwd');
Nous devons maintenant faire la comparaison, puis renvoyer NULL ou un objet d'erreur..
import AbstractControl à partir de '@ angular / forms'; fonction d'exportation passwordMatch (control: AbstractControl): [clé: chaîne de caractères]: boolean // Saisir un mot de passe et confirmer un mot de passe à l'aide de control.get const pwd = control.get ('pwd'); const confirmPwd = control.get ('confirmPwd'); // Si les objets FormControl n'existent pas, retourne null si (! Pwd ||! ConfirmPwd) return null; // S'ils sont bien égaux, renvoie null si (pwd.value === confirmPwd.value) return null; // Sinon return false return mismatch: true;
Pourquoi ai-je remplacé FormGroup
avec AbstractControl
? comme vous le savez, AbstractControl
est la mère de toutes les classes de formulaire * et vous donne plus de contrôle sur les objets de contrôle de formulaire. Cela a l'avantage supplémentaire de rendre notre code de validation plus cohérent.
Importer le passwordMatch
fonctionner dans le SignupForm
composant et le déclarer comme un validateur pour le mot de passe FormGroup
exemple.
import passwordMatch de './… / password-match';… la classe d'exportation SignupFormComponent implémente OnInit ngOnInit () // Utilisez le formbuilder pour créer le modèle de formulaire this.signupForm = this.fb.group (… mot_de_passe: this.fb.group (pwd: [", [Validators.required, Validators.minLength (8)]], confirmPwd: [", [Validators.required, Validators.minLength (8)]],: validator: passwordMatch ),…)
Si vous avez tout fait correctement, password.errors? .mismatch
sera vrai chaque fois que les valeurs des deux champs ne correspondent pas.
password.errors? .mismatch json
Bien qu'il existe d'autres moyens d'afficher les erreurs, je vais utiliser le ngIf
directive pour déterminer si un message d'erreur doit être affiché ou non.
Tout d'abord, je vais utiliser ngIf
pour voir si le mot de passe est invalide.
Nous utilisons mot de passe.touched
pour s'assurer que l'utilisateur ne reçoit pas d'erreurs avant même d'appuyer sur une touche.
Ensuite, je vais utiliser la syntaxe ngIf = "expression; puis a else b" pour afficher la bonne erreur..
Le mot de passe ne correspond pas Le mot de passe doit comporter plus de 8 caractères.
Voilà, un modèle de travail du validateur qui vérifie l’égalité des mots de passe.
Nous utiliserons la même fonction de validation que nous avons créée précédemment pour le formulaire piloté par le modèle. Cependant, nous n’avons pas un accès direct aux instances de FormControl
/FormGroup
sous forme de gabarit. Voici ce que vous devrez faire pour que le validateur fonctionne:
PasswordMatchDirective
qui sert d’emballage autour du passwordMatch
fonction de validation. Nous enregistrerons la directive en tant que validateur en utilisant le NG_VALIDATORS
fournisseur. Plus sur cela plus tard.Écrivons d'abord la directive. Voici à quoi ressemble une directive dans Angular:
import AbstractControl à partir de '@ angular / forms'; fonction d'exportation passwordMatch (control: AbstractControl): [clé: chaîne de caractères]: boolean // Saisir un mot de passe et confirmer un mot de passe à l'aide de control.get const pwd = control.get ('pwd'); const confirmPwd = control.get ('confirmPwd'); // Si les objets FormControl n'existent pas, retourne null si (! Pwd ||! ConfirmPwd) return null; // S'ils sont bien égaux, renvoie null si (pwd.value === confirmPwd.value) return null; // Sinon return false return mismatch: true; // PasswordMatchDirective @Directive (sélecteur: ", fournisseurs: []) classe d'exportation PasswordMatchDirective
le @Directif
décorator est utilisé pour marquer la classe en tant que directive angulaire. Il accepte un objet en tant qu'argument spécifiant les métadonnées de configuration de la directive, telles que les sélecteurs auxquels la directive doit être attachée, et la liste des fournisseurs à injecter, etc. Remplissons les métadonnées de la directive:
@Directive (sélecteur: '[passwordMatch] [ngModelGroup]', // 1 fournisseurs: [// 2 fournir: NG_VALIDATORS, useValue: passwordMatch, multi: true]) classe d'exportation PasswordMatchDirective
ngModelGroup
et passwordMatch
. NG_VALIDATORS
fournisseur. Comme mentionné précédemment, NG_VALIDATORS
est un fournisseur qui possède une collection extensible de validateurs. le passwordMatch
La fonction que nous avons créée précédemment est déclarée en tant que dépendance. le multi: vrai
définit ce fournisseur pour être un multi-fournisseur. Cela signifie que nous allons ajouter à la collection existante de validateurs fournie par NG_VALIDATORS
.Maintenant, ajoutez la directive au tableau de déclarations dans ngModule
.
… Importer PasswordMatchDirective de './password-match'; @NgModule (declarations: [AppComponent, SignupFormComponent, PasswordMatchDirective], importations: [BrowserModule, FormsModule], fournisseurs: [], bootstrap: [AppComponent]) classe d'exportation AppModule .
Pour afficher les messages d'erreur de validation, je vais utiliser le même modèle que nous avons créé pour les formulaires dirigés par un modèle..
Le mot de passe ne correspond pas Le mot de passe doit comporter plus de 8 caractères.
Dans ce tutoriel, nous avons appris à créer des validateurs angulaires personnalisés pour les formulaires en mode angulaire..
Les validateurs sont des fonctions qui renvoient null ou un objet d'erreur. Dans les formulaires dirigés par un modèle, nous devons associer le validateur à une instance FormControl / FormGroup, et c'est tout. La procédure était un peu plus complexe dans un formulaire basé sur des modèles car nous devions créer une directive par-dessus la fonction de validation..
Si vous souhaitez continuer à en apprendre davantage sur JavaScript, n'oubliez pas de consulter ce que nous avons dans le marché Envato..
J'espère que vous avez apprécié cette série sur Forms in Angular. Je serais ravi d'entendre vos pensées. Partagez-les à travers les commentaires.