Questa è la terza parte della serie sulla creazione di moduli in Angular. Nei primi due tutorial, abbiamo utilizzato l'approccio basato su modelli e guidato da modelli di Angular per la creazione di moduli. Tuttavia, mentre descrivevo entrambi gli approcci, c'era qualcosa che non coprivamo: funzioni di validazione personalizzate. Questo tutorial coprirà tutto ciò che devi sapere sulla stesura di validatori personalizzati che soddisfano le tue esigenze.
Non è necessario aver seguito la prima o la seconda parte di questa serie per la terza parte. Tuttavia, se sei completamente nuovo per le forme in Angular, dovresti andare al primo tutorial di questa serie e iniziare da lì.
Altrimenti, prendi una copia di questo codice dal nostro repository GitHub e usalo come punto di partenza.
Angular non vanta un'enorme libreria di validatori incorporata. A partire da Angular 4, abbiamo i seguenti validatori popolari in Angular:
Ce ne sono altri ancora e puoi vedere l'elenco completo nei documenti Angular.
Possiamo utilizzare i suddetti validatori predefiniti in due modi:
1. Come direttive in moduli basati su modelli.
2. Come validatori all'interno del FormControl
costruttore in moduli basati su modelli.
name = new FormControl (", Validators.required)
Se la sintassi di cui sopra non ha senso, segui le mie esercitazioni precedenti sulla creazione di un modulo di iscrizione utilizzando un approccio basato su modelli o un approccio basato sul modello e quindi tornare indietro!
I validatori di moduli incorporati coprono a malapena tutti i casi di utilizzo della convalida che potrebbero essere richiesti in un'applicazione reale. Ad esempio, un modulo di registrazione potrebbe dover verificare se i valori della password e i campi di controllo della password di conferma sono uguali e visualizzare un messaggio di errore se non corrispondono. Un validatore che le e-mail nere da un determinato dominio è un altro esempio comune.
Ecco un dato di fatto: le forme basate su modelli sono solo forme guidate dal modello sottostante. In un modulo basato sui modelli, lasciamo che il modello si occupi della creazione del modello per noi. La domanda ovvia ora è, come si allega un validatore a un modulo?
I validatori sono solo funzioni. In un modello guidato dal modello, allegare i validatori a FormControl è semplice. In un modulo basato su modelli, tuttavia, c'è ancora un po 'di lavoro da fare. Oltre alla funzione di convalida, sarà necessario scrivere una direttiva per il validatore e creare istanze della direttiva nel modello.
Sebbene questo sia già stato trattato, faremo un rapido riassunto del codice per il modulo di registrazione. Innanzitutto, ecco l'approccio reattivo.
// Usa il formbuilder per costruire il modello Form this.signupForm = this.fb.group (email: [", [Validators.required, Validators.pattern ('[a-z0-9 ._% + -] + @ [a-z0-9 .-] + \. [az] 2,3 $ ')]], password: this.fb.group (pwd: [", [Validators.required, Validators.minLength (8 )]], confirmPwd: [", [Validators.required, Validators.minLength (8)]], validator: PasswordMatch), gender: [", Validators.required],)
FormBuilder
è uno zucchero sintassi che crea il FormGroup
e FormControl
le istanze. UN FormControl
tiene traccia del valore e dello stato di convalida di un singolo elemento del modulo. UN FormGroup
, d'altra parte, comprende un gruppo di FormControl
istanze e tiene traccia del valore e della validità dell'intero gruppo.
Ecco la struttura che abbiamo seguito:
FormGroup -> 'signupForm' FormControl -> 'email' FormGroup -> 'password' FormControl -> 'pwd' FormControl -> 'confirmPwd' FormControl -> 'gender'
A seconda dei requisiti, possiamo allegare un validatore a a FormControl
o a FormGroup
. Un validatore di blacklist per e-mail richiederebbe che sia allegato al FormControl
istanza dell'email.
Tuttavia, per convalide più complesse in cui è necessario confrontare e convalidare più campi di controllo, è consigliabile aggiungere la logica di convalida al genitore FormGroup
. Come potete vedere, parola d'ordine
ha un FormGroup
di per sé, e questo rende facile per noi scrivere i validatori che controllano l'uguaglianza di pwd
e confirmPwd
.
Per il modulo basato sui modelli, tutta la logica va nel modello HTML e qui c'è un esempio:
ngModel
crea un'istanza di FormControl
e lo lega a un elemento di controllo del modulo. allo stesso modo, ngModelGroup
crea e lega a FormGroup
istanza ad un elemento DOM. Condividono la stessa struttura di dominio modello discussa sopra.
È anche interessante notare che FormControl
, FormGroup
, e FormArray
estendere la AbstractControl
classe. Ciò significa che il AbstractControl
la classe è responsabile del rilevamento dei valori degli oggetti del modulo, della loro convalida e dell'alimentazione di altri elementi come metodi puliti, sporchi e toccati.
Ora che conosciamo entrambe le tecniche di form, scriviamo il nostro primo validatore personalizzato.
I validatori sono funzioni che prendono un FormControl
/FormGroup
istanza come input e ritorno nullo
o un oggetto errore. nullo
viene restituito quando la convalida ha esito positivo e, in caso contrario, viene generato l'oggetto errore. Ecco una versione di base di una funzione di convalida.
importare FormGroup da '@ angular / forms'; export function passwordMatch (control: FormGroup): [key: string]: boolean
Ho dichiarato una funzione che accetta un'istanza di FormGroup
come input. Restituisce un oggetto con una chiave di tipo stringa e un valore vero / falso. Questo è così che possiamo restituire un oggetto error del modulo sottostante:
mancata corrispondenza: vero
Successivamente, dobbiamo ottenere il valore di pwd
e confirmPwd
Istanze di FormControl. Ho intenzione di usare control.get ()
per prendere i loro valori.
export function passwordMatch (control: FormGroup): [key: string]: boolean // Grab pwd e confirmPwd utilizzando control.get const pwd = control.get ('pwd'); const confirmPwd = control.get ('confirmPwd');
Ora dobbiamo fare il confronto e quindi restituire null o un oggetto di errore.
import AbstractControl da '@ angular / forms'; export function passwordMatch (control: AbstractControl): [key: string]: boolean // Grab pwd e confirmPwd utilizzando control.get const pwd = control.get ('pwd'); const confirmPwd = control.get ('confirmPwd'); // Se gli oggetti FormControl non esistono, restituisce null se (! Pwd ||! ConfirmPwd) restituisce null; // Se sono effettivamente uguali, restituisce null se (pwd.value === confirmPwd.value) return null; // Else return false return mismatch: true;
Perché ho sostituito FormGroup
con AbstractControl
? Come sai, AbstractControl
è la madre di tutte le classi di Form * e ti dà un maggiore controllo sugli oggetti di controllo del modulo. Ha il vantaggio aggiunto che rende il nostro codice di convalida più coerente.
Importa il passwordMatch
funzione nel SignupForm
componente e dichiararlo come validatore per la password FormGroup
esempio.
import passwordMatch da './... / password-match'; ... export class SignupFormComponent implementa OnInit ngOnInit () // Usa il formbuilder per costruire il modello Form this.signupForm = this.fb.group (... password: this.fb.group (pwd: [", [Validators.required, Validators.minLength (8)]], confirmPwd: [", [Validators.required, Validators.minLength (8)]], validator: passwordMatch ), ...)
Se hai fatto tutto bene, password.errors? .mismatch
sarà vero ogni volta che i valori di entrambi i campi non corrispondono.
password.errors? .mismatch json
Sebbene ci siano metodi alternativi per visualizzare gli errori, userò il ngIf
direttiva per determinare se un messaggio di errore debba essere visualizzato o meno.
Per prima cosa, userò ngIf
per vedere se la password non è valida.
Noi usiamo password.touched
per garantire che l'utente non sia salutato con errori anche prima che un tasto sia stato premuto.
Successivamente, userò la sintassi ngIf = "expression; then a else b" per visualizzare l'errore corretto.
La password non coincide La password deve contenere più di 8 caratteri
Eccolo lì, un modello funzionante del validatore che controlla l'uguaglianza delle password.
Utilizzeremo la stessa funzione di validatore che abbiamo creato per la forma guidata dal modello in precedenza. Tuttavia, non abbiamo accesso diretto alle istanze di FormControl
/FormGroup
in una forma guidata da un modello. Ecco le cose che devi fare per far funzionare il validatore:
PasswordMatchDirective
che funge da involucro attorno al passwordMatch
funzione di validatore. Registreremo la direttiva come validatore usando il NG_VALIDATORS
fornitore. Maggiori informazioni su questo più tardi.Scriviamo prima la direttiva. Ecco come appare una direttiva in Angular:
import AbstractControl da '@ angular / forms'; export function passwordMatch (control: AbstractControl): [key: string]: boolean // Grab pwd e confirmPwd utilizzando control.get const pwd = control.get ('pwd'); const confirmPwd = control.get ('confirmPwd'); // Se gli oggetti FormControl non esistono, restituisce null se (! Pwd ||! ConfirmPwd) restituisce null; // Se sono effettivamente uguali, restituisce null se (pwd.value === confirmPwd.value) return null; // Else return false return mismatch: true; // PasswordMatchDirective @Directive (selector: ", providers: []) classe di esportazione PasswordMatchDirective
Il @Direttiva
decoratore è usato per marcare la classe come una direttiva angolare. Accetta un oggetto come argomento che specifica i metadati di configurazione della direttiva, come i selettori per i quali la direttiva deve essere allegata e l'elenco dei provider da iniettare, ecc. Compiliamo i metadati della direttiva:
@Directive (selector: '[passwordMatch] [ngModelGroup]', // 1 provider: [// 2 fornire: NG_VALIDATORS, useValue: passwordMatch, multi: true]) classe di esportazione PasswordMatchDirective
ngModelGroup
e passwordMatch
. NG_VALIDATORS
fornitore. Come precedentemente menzionato, NG_VALIDATORS
è un fornitore che ha una collezione estensibile di validatori. Il passwordMatch
la funzione che abbiamo creato in precedenza è dichiarata come dipendenza. Il multi: vero
imposta questo provider come multi-provider. Ciò significa che aggiungeremo alla raccolta esistente di validatori fornita da NG_VALIDATORS
.Ora, aggiungi la direttiva all'array delle dichiarazioni in ngModule
.
... import PasswordMatchDirective da './password-match'; @NgModule (dichiarazioni: [AppComponent, SignupFormComponent, PasswordMatchDirective], importa: [BrowserModule, FormsModule], provider: [], bootstrap: [AppComponent]) classe di esportazione AppModule
Per visualizzare i messaggi di errore di convalida, utilizzerò lo stesso modello che abbiamo creato per i moduli basati sul modello.
La password non coincide La password deve contenere più di 8 caratteri
In questo tutorial, abbiamo imparato a creare validatori angolari personalizzati per moduli in Angular.
I validatori sono funzioni che restituiscono null o un oggetto errore. Nei moduli basati su modelli, dobbiamo allegare il validatore a un'istanza FormControl / FormGroup e il gioco è fatto. La procedura era un po 'più complessa in un modulo basato su template perché avevamo bisogno di creare una direttiva sulla parte superiore della funzione validator.
Se sei interessato a continuare a saperne di più su JavaScript, ricorda di controllare cosa abbiamo in Envato Market.
Spero che questa serie ti sia piaciuta su Forms in Angular. Mi piacerebbe sentire i tuoi pensieri. Condividili attraverso i commenti.