Convalida del campo trasversale in Angular2

Sto costruendo un’applicazione per client Angular2. Attualmente sto lavorando sui componenti di appartenenza e sull’integrazione dei componenti lato client con MVC6 vNext Identity v3. Ho scritto i validatori di password Angular2 personalizzati come segue:

needsCapitalLetter(ctrl: Control): {[s: string]: boolean} { if(!ctrl.value.match(/[AZ]/)) return {'needsCapitalLetter': true} return null; } needsLowerLetter(ctrl: Control): {[s: string]: boolean} { if(!ctrl.value.match(/[az]/)) return {'needsLowerLetter': true} return null; } needsNumber(ctrl: Control): {[s: string]: boolean} { if(!ctrl.value.match(/\d/)) return {'needsNumber': true} return null; } needsSpecialCharacter(ctrl: Control): {[s: string]: boolean} { if(!ctrl.value.match(/[^a-zA-Z\d]/)) return {'needsSpecialCharacter': true} return null; } 

Questo lavoro funziona alla grande e mi piace Angular2, ma ora sto cercando di scrivere un validatore che verifichi che la “Conferma password” sia uguale alla “Password”. Per fare questo, ho bisogno di essere in grado di convalidare un campo contro l’altro. Posso farlo facilmente a livello di componente, e controllare solo sfocatura, o su invio, o un numero qualsiasi di altri modi, ma questo aggira il sistema di validazione di Angular2 ngForm. Mi piacerebbe molto capire come scrivere un Validatore Angular2 per un campo in grado di verificare il valore di un altro campo, passando il nome dell’altro campo o qualcosa di simile. Sembra che questa dovrebbe essere una capacità in quanto sarebbe una necessità in quasi tutte le UI di applicazioni aziendali complesse.

È necessario assegnare un validatore personalizzato a un gruppo di moduli completo per implementarlo. Qualcosa come questo:

 this.form = this.fb.group({ name: ['', Validators.required], email: ['', Validators.required] matchingPasswords: this.fb.group({ password: ['', Validators.required], confirmPassword: ['', Validators.required] }, {validator: this.matchValidator}) <-------- }); 

In questo modo avrai accesso a tutti i controlli del gruppo e non solo a uno ... È ansible accedervi utilizzando la proprietà controls del FormGroup. Il FormGroup viene fornito quando viene triggersta la convalida. Per esempio:

 matchValidator(group: FormGroup) { var valid = false; for (name in group.controls) { var val = group.controls[name].value (...) } if (valid) { return null; } return { mismatch: true }; } 

Vedi questa domanda per maggiori dettagli:

  • Validatore Angular2 che si basa su più campi modulo

Puoi anche utilizzare un validatore di direttive personalizzate per confrontare i campi.

Nel tuo html:

 
Password is required
Password mismatch

E la tua direttiva:

 import { Directive, forwardRef, Attribute } from '@angular/core'; import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms'; @Directive({ selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]', providers: [ { provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true } ] }) export class EqualValidator implements Validator { constructor( @Attribute('validateEqual') public validateEqual: string) {} validate(c: AbstractControl): { [key: string]: any } { // self value (eg retype password) let v = c.value; // control value (eg password) let e = c.root.get(this.validateEqual); // value not equal if (e && v !== e.value) return { validateEqual: false } return null; } } 

Ecco la soluzione completa in plunkr:

https://plnkr.co/edit/KgjSTj7VqbWMnRdYZdxM?p=preview

Non l’ho fatto da solo, ma è ansible creare ControlGroup con due campi password e convalidarlo. I controlli hanno proprietà .valueChanges che è osservabile e puoi combinarli e controllare l’uguaglianza.

Victor Savkin parla brevemente di quel caso esatto su Angular Air in questo episodio