Inleiding tot formulieren in Angular 4 Validators voor aangepaste formulieren schrijven

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.

voorwaarden

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.  

Ingebouwde validators

Angular beschikt niet over een enorme ingebouwde validatorbibliotheek. Vanaf Angular 4 hebben we de volgende populaire validators in Angular:

  • verplicht
  • minimale lengte
  • maximale lengte
  • patroon

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.

Duiken in de details

Hoewel dit al is behandeld, zullen we een korte samenvatting van de code voor het aanmeldingsformulier doornemen. Ten eerste, hier is de reactieve benadering.

app / aanmelden-form / aanmelden-form.component.ts

 // 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:

app / aanmelden-form / aanmelden-form.component.html

...

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.

Custom Validator-functie voor formuliergedreven formulieren

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. 

app / wachtwoord-match.ts

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.

app / wachtwoord-match.ts

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.

app / wachtwoord-match.ts

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 ), ...) 

De fouten weergeven

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.

app / aanmelden-form / aanmelden-form.component.html

    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.

Demo voor aangepaste validators in formuliergedreven formulieren

Aangepaste validatorrichtlijn voor sjabloongestuurde formulieren

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:

  1. Maak een 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.
  2. Voeg de richtlijn toe aan het sjabloonvormbeheer. 

Laten we eerst de richtlijn schrijven. Dit is hoe een richtlijn er in Angular uitziet:

app / wachtwoord-match.ts

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:

app / wachtwoord-match.ts

@Richtlijn (selector: '[passwordMatch] [ngModelGroup]', // 1 providers: [// 2 provide: NG_VALIDATORS, useValue: passwordMatch, multi: true]) exportklasse PasswordMatchDirective 
  1. De richtlijn is nu gekoppeld aan alle invoerbesturingselementen met de kenmerken ngModelGroup en passwordMatch
  2. We breiden de ingebouwde validators uit met behulp van de 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.

app / app.module.ts

... importeer PasswordMatchDirective van './password-match'; @ NgModule (declarations: [AppComponent, SignupFormComponent, PasswordMatchDirective], imports: [BrowserModule, FormsModule], providers: [], bootstrap: [AppComponent]) exportklasse AppModule  

Foutmeldingen weergeven

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

Conclusie

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.