Dit is het derde deel van de serie over het maken van vormen in Angular. In de eerste twee tutorials gebruikten we de sjabloongestuurde en modelgestuurde aanpak van Angular om formulieren te maken. Hoewel we beide benaderingen gedetailleerd beschreven, was er iets dat we niet behandelden: aangepaste validatiefuncties. Deze tutorial behandelt alles wat u moet weten over het schrijven van aangepaste validators die aan uw vereisten voldoen.
U hoeft deel een of twee van deze serie niet te hebben gevolgd om deel drie duidelijk te maken. Als u echter volledig nieuw bent in formulieren in Angular, gaat u naar de eerste zelfstudie van deze serie en begint u daar.
Neem anders een kopie van deze code van onze GitHub-repo en gebruik die als uitgangspunt.
Angular beschikt niet over een enorme ingebouwde validatorbibliotheek. Vanaf Angular 4 hebben we de volgende populaire validators in Angular:
Er zijn er nog enkele, en je kunt de volledige lijst in de Angular-documenten zien.
We kunnen de bovenstaande ingebouwde validators op twee manieren gebruiken:
1. Als richtlijnen in sjabloongestuurde formulieren.
2. Als validators binnen de FormControl
constructeur in modelgestuurde vormen.
name = new FormControl (", Validators.verplicht)
Als de bovenstaande syntaxis niet klopt, volg dan mijn eerdere zelfstudies over het maken van een aanmeldingsformulier met behulp van een sjabloongestuurde aanpak of een modelgestuurde aanpak en laat u vervolgens terugvallen!
De ingebouwde formuliervalidators dekken nauwelijks alle validatiegebruiksgevallen die mogelijk vereist zijn in een toepassing uit de praktijk. Een aanmeldingsformulier moet bijvoorbeeld controleren of de waarden van het wachtwoord en de velden voor het bevestigen van het wachtwoord gelijk zijn en een foutmelding weergeven als ze niet overeenkomen. Een ander voorbeeld is een validator die e-mails van een bepaald domein op de zwarte lijst zet.
Hier is een feit: sjabloongestuurde vormen zijn slechts modelgestuurde vormen eronder. In een sjabloongestuurde vorm laten we de sjabloon zorgen voor het maken van het model voor ons. De voor de hand liggende vraag is nu: hoe bevestig je een validator aan een formulier??
Validators zijn slechts functies. In een modelgestuurde vorm is het koppelen van validators aan FormControl eenvoudig. In een sjabloongestuurde vorm is er echter iets meer werk aan de winkel. Naast de validatiefunctie moet u een richtlijn voor de validator schrijven en exemplaren van de richtlijn in de sjabloon maken.
Hoewel dit al is behandeld, zullen we een korte samenvatting van de code voor het aanmeldingsformulier doornemen. Ten eerste, hier is de reactieve benadering.
// Gebruik de formbuilder om het formuliermodel te bouwen this.signupForm = this.fb.group (email: [", [Validators.required, Validators.pattern ('[a-z0-9 ._% + -] + @ [a-z0-9 .-] + \. [az] 2,3 $ ')]], wachtwoord: this.fb.group (pwd: [", [Validators.required, Validators.minLength (8 )]], confirmPwd: [", [Validators.required, Validators.minLength (8)]], validator: PasswordMatch), geslacht: [", Validators.required],)
FormBuilder
is een syntaxisuiker die de FormGroup
en FormControl
instances. EEN FormControl
traceert de waarde en de validatiestatus van een individueel formulierelement. EEN FormGroup
, aan de andere kant, bestaat uit een groep FormControl
instanties, en het volgt de waarde en validiteit van de hele groep.
Dit is de structuur die we hebben gevolgd:
FormGroup -> 'signupForm' FormControl -> 'email' FormGroup -> 'password' FormControl -> 'pwd' FormControl -> 'confirmPwd' FormControl -> 'gender'
Afhankelijk van de vereisten kunnen we een validator bijvoegen bij een FormControl
of a FormGroup
. Een validerende e-mailbevestiging voor blacklist vereist dat deze wordt bijgevoegd bij de FormControl
exemplaar van de e-mail.
Voor complexere validaties waarbij meerdere controlevelden moeten worden vergeleken en gevalideerd, is het echter een beter idee om de validatielogica toe te voegen aan de bovenliggende FormGroup
. Zoals je kunt zien, wachtwoord
heeft een FormGroup
van zijn eigen, en dit maakt het gemakkelijk voor ons om validators te schrijven die de gelijkheid van controleren pwd
en confirmPwd
.
Voor de sjabloongestuurde vorm gaat al die logica in de HTML-sjabloon en hier is een voorbeeld:
ngModel
maakt een instantie van FormControl
en bindt het aan een formulierbesturingselement. evenzo, ngModelGroup
maakt en bindt een FormGroup
bijvoorbeeld naar een DOM-element. Ze delen dezelfde domeinstructuurstructuur als hierboven besproken.
Het is ook interessant om op te merken dat FormControl
, FormGroup
, en FormArray
verleng de AbstractControl
klasse. Wat dit betekent is dat de AbstractControl
class is verantwoordelijk voor het bijhouden van de waarden van formulierobjecten, het valideren ervan en het aandrijven van andere zaken zoals onberispelijke, vuile en aangeraakte methoden.
Nu we bekend zijn met zowel de formuliertechnieken, laten we onze eerste aangepaste validator schrijven.
Validators zijn functies die een FormControl
/FormGroup
bijvoorbeeld als invoer en retour nul
of een foutobject. nul
wordt geretourneerd wanneer de validatie is gelukt, en zo niet, dan wordt het fout-object gegenereerd. Hier is een zeer eenvoudige versie van een validatiefunctie.
importeer FormGroup uit '@ angular / forms'; exportfunctie passwordMatch (controle: FormGroup): [key: string]: boolean
Ik heb een functie opgegeven die een instantie van accepteert FormGroup
als een input. Het retourneert een object met een sleutel van het type tekenreeks en een waarde true / false. Dit is zodat we een fout object van het onderstaande formulier kunnen retourneren:
mismatch: true
Vervolgens moeten we de waarde van de pwd
en confirmPwd
FormControl-instanties. Ik ga gebruiken control.get ()
om hun waarden op te halen.
exportfunctie passwordMatch (controle: FormGroup): [key: string]: boolean // Pak pwd en bevestigPwd met control.get const pwd = control.get ('pwd'); const confirmPwd = control.get ('confirmPwd');
Nu moeten we de vergelijking maken en vervolgens nul of een foutobject retourneren.
importeer AbstractControl uit '@ angular / forms'; exportfunctie passwordMatch (controle: AbstractControl): [key: string]: boolean // Pak pwd en bevestigPwd met control.get const pwd = control.get ('pwd'); const confirmPwd = control.get ('confirmPwd'); // Als FormControl-objecten niet bestaan, retourneert u null als (! Pwd ||! ConfirmPwd) null retourneert; // Als ze inderdaad gelijk zijn, retourneer null als (pwd.value === confirmPwd.value) return null; // Anders return false return mismatch: true;
Waarom heb ik vervangen? FormGroup
met AbstractControl
? Zoals je weet, AbstractControl
is de moeder van alle Form * -klassen en geeft u meer controle over de formulierbesturingsobjecten. Het heeft het extra voordeel dat het onze validatiecode consistenter maakt.
Importeer de passwordMatch
functie in de SignupForm
component en declareren als een validator voor het wachtwoord FormGroup
aanleg.
import passwordMatch van './... / password-match'; ... export class SignupFormComponent implementeert OnInit ngOnInit () // Gebruik de formbuilder om het formuliermodel te bouwen this.signupForm = this.fb.group (... wachtwoord: this.fb.group (pwd: [", [Validators.required, Validators.minLength (8)]], confirmPwd: [", [Validators.required, Validators.minLength (8)]], validator: passwordMatch ), ...)
Als je alles goed hebt gedaan, password.errors? .mismatch
zal waar zijn telkens als de waarden van beide velden niet overeenkomen.
password.errors? .mismatch json
Hoewel er alternatieve manieren zijn om fouten weer te geven, ga ik de ngIf
richtlijn om te bepalen of een foutmelding moet worden weergegeven of niet.
Eerst ga ik gebruiken ngIf
om te zien of het wachtwoord ongeldig is.
We gebruiken password.touched
om ervoor te zorgen dat de gebruiker niet wordt begroet met fouten, zelfs voordat een toets is ingedrukt.
Vervolgens ga ik de ngIf = "expressie gebruiken, gevolgd door een andere b" -syntaxis om de juiste fout weer te geven.
Wachtwoord komt niet overeen Wachtwoord moet uit meer dan 8 tekens bestaan
Daar heb je het, een werkend model van de validator die controleert op wachtwoordgelijkheid.
We zullen dezelfde validatiefunctie gebruiken die we eerder voor de modelgestuurde vorm hebben gemaakt. We hebben echter geen directe toegang tot exemplaren van FormControl
/FormGroup
in een sjabloongestuurde vorm. Dit zijn de dingen die u moet doen om de validator te laten werken:
PasswordMatchDirective
dat dient als een omslag om de passwordMatch
validator functie. We zullen de richtlijn als een validator registreren met behulp van de NG_VALIDATORS
provider. Hierover later meer.Laten we eerst de richtlijn schrijven. Dit is hoe een richtlijn er in Angular uitziet:
importeer AbstractControl uit '@ angular / forms'; exportfunctie passwordMatch (controle: AbstractControl): [key: string]: boolean // Pak pwd en bevestigPwd met control.get const pwd = control.get ('pwd'); const confirmPwd = control.get ('confirmPwd'); // Als FormControl-objecten niet bestaan, retourneert u null als (! Pwd ||! ConfirmPwd) null retourneert; // Als ze inderdaad gelijk zijn, retourneer null als (pwd.value === confirmPwd.value) return null; // Anders return false return mismatch: true; // PasswordMatchDirective @Directive (selector: ", providers: []) exportklasse PasswordMatchDirective
De @Richtlijn
decorateur wordt gebruikt om de klasse te markeren als een hoekrichtlijn. Het accepteert een object als een argument dat de metagegevens van de richtlijnconfiguratie specificeert, zoals selectors waarvoor de richtlijn moet worden bijgevoegd, en de lijst met in te spuiten leveranciers. Laten we de metadata van de richtlijn invullen:
@Richtlijn (selector: '[passwordMatch] [ngModelGroup]', // 1 providers: [// 2 provide: NG_VALIDATORS, useValue: passwordMatch, multi: true]) exportklasse PasswordMatchDirective
ngModelGroup
en passwordMatch
. NG_VALIDATORS
provider. Zoals eerder vermeld, NG_VALIDATORS
is een provider met een uitbreidbare verzameling validators. De passwordMatch
functie die we eerder hebben aangemaakt wordt verklaard als een afhankelijkheid. De multi: true
stelt deze provider in als een multi-provider. Wat dit betekent is dat we zullen toevoegen aan de bestaande verzameling validators die door NG_VALIDATORS
.Voeg nu de richtlijn toe aan de aangiftearray in ngModule
.
... importeer PasswordMatchDirective van './password-match'; @ NgModule (declarations: [AppComponent, SignupFormComponent, PasswordMatchDirective], imports: [BrowserModule, FormsModule], providers: [], bootstrap: [AppComponent]) exportklasse AppModule
Om de validatiefoutberichten weer te geven, gebruik ik dezelfde sjabloon die we hebben gemaakt voor de modelgestuurde formulieren.
Wachtwoord komt niet overeen Wachtwoord moet uit meer dan 8 tekens bestaan
In deze zelfstudie leerden we over het maken van aangepaste hoekige validators voor vormen in Angular.
Validators zijn functies die null of een foutobject retourneren. In modelgestuurde formulieren moeten we de validator koppelen aan een instantie van FormControl / FormGroup, en dat is alles. De procedure was wat complexer in een sjabloongestuurde vorm omdat we een richtlijn moesten opstellen bovenop de validatiefunctie.
Als u meer wilt weten over JavaScript, vergeet dan niet om te controleren wat we hebben in Envato Market.
Ik hoop dat je deze serie hebt genoten op Forms in Angular. Ik zou graag je gedachten horen. Deel ze via de opmerkingen.