2016-03-26 26 views
11

Ho un problema con la definizione del validatore asincrono in un modello guidato da modello.Validatore asincrono basato su modello angolare2

Attualmente ho questo ingresso:

<input type="text" ngControl="email" [(ngModel)]="model.applicant.contact.email" #email="ngForm" required asyncEmailValidator> 

con selettore validatore asyncEmailValidator che è rivolta a questa classe:

import {provide} from "angular2/core"; 
import {Directive} from "angular2/core"; 
import {NG_VALIDATORS} from "angular2/common"; 
import {Validator} from "angular2/common"; 
import {Control} from "angular2/common"; 
import {AccountService} from "../services/account.service"; 

@Directive({ 
selector: '[asyncEmailValidator]', 
providers: [provide(NG_VALIDATORS, {useExisting: EmailValidator, multi: true}), AccountService] 
}) 

export class EmailValidator implements Validator { 
//https://angular.io/docs/ts/latest/api/common/Validator-interface.html 


constructor(private accountService:AccountService) { 
} 

validate(c:Control):{[key: string]: any} { 
    let EMAIL_REGEXP = /^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i; 

    if (!EMAIL_REGEXP.test(c.value)) { 
     return {validateEmail: {valid: false}}; 
    } 

    return null; 

    /*return new Promise(resolve => 
     this.accountService.getUserNames(c.value).subscribe(res => { 
      if (res == true) { 
       resolve(null); 
      } 
      else { 
       resolve({validateEmailTaken: {valid: false}}); 
      } 
     }));*/ 
} 

}

Email parte regex funziona come previsto e il modulo viene convalidato correttamente se la regex corrisponde. Ma dopo voglio controllare se l'e-mail non è già in uso, quindi sto creando promesse per il mio accountService. Ma questo non funziona affatto e la forma è sempre nello stato fallito.

che ho letto su modello guidato forme e l'utilizzo di FormBuilder come di seguito:

constructor(builder: FormBuilder) { 
this.email = new Control('', 
    Validators.compose([Validators.required, CustomValidators.emailFormat]), CustomValidators.duplicated 
); 
} 

Quali sono i validatori asincroni definita nel terzo parametro di Control() Ma questo non è il mio caso, perché im utilizzando approccio differente .

Quindi, la mia domanda è: è possibile creare un validatore asincrono utilizzando i moduli basati su modelli?

risposta

13

Si potrebbe provare a registrare il provider del validatore asincrona con la chiave NG_ASYNC_VALIDATORS e non il NG_VALIDATORS una (solo per i validatori sincroni):

@Directive({ 
    selector: '[asyncEmailValidator]', 
    providers: [ 
    provide(NG_ASYNC_VALIDATORS, { // <------------ 
     useExisting: EmailValidator, multi: true 
    }), 
    AccountService 
    ] 
}) 
export class EmailValidator implements Validator { 
    constructor(private accountService:AccountService) { 
    } 

    validate(c:Control) { 
    return new Promise(resolve => 
     this.accountService.getUserNames(c.value).subscribe(res => { 
     if (res == true) { 
      resolve(null); 
     } 
     else { 
      resolve({validateEmailTaken: {valid: false}}); 
     } 
    })); 
    } 
} 

Vedere questo documento sul sito angular.io:

+0

Grazie! Questo è esattamente quello che volevo. Btw. È possibile combinare la parte asincrona del validatore (promessa) con la parte noasync (solo regex) in una classe validatore in modo tale che la parte asincrona verrà avviata solo se l'espressione regolare è OK o se ho bisogno di entrambi separatamente? – Marduk

+0

Sì, ma è possibile, in entrambi i casi, è necessario per risolvere la promessa. Quest'ultimo può essere risolto anche se l'elaborazione non è asincrona ... –

+0

Ok, ci proverò. Grazie ancora. – Marduk

1

pena notare che la sintassi è cambiato da th it, ora sto usando angolare 4, e qui sotto una riscrittura:

import { Directive, forwardRef } from '@angular/core'; 
import { AbstractControl, Validator, NG_ASYNC_VALIDATORS } from '@angular/forms'; 
import { AccountService } from 'account.service'; 

@Directive({ 
    selector: '[asyncEmailValidator]', 
    providers: [ 
     { 
      provide: NG_ASYNC_VALIDATORS, 
      useExisting: forwardRef(() => EmailValidatorDirective), multi: true 
     }, 
    ] 
}) 
export class EmailValidatorDirective implements Validator { 
    constructor(private _accountService: AccountService) { 
    } 

    validate(c: AbstractControl) { 
     return new Promise(resolve => 
      this._accountService.isEmailExists(c.value).subscribe(res => { 
       if (res == true) { 
        resolve({ validateEmailTaken: { valid: false } }); 
       } 
       else { 
        resolve(null); 
       } 
      })); 
    } 
} 
Problemi correlati