2017-09-06 31 views
3

我想检查电子邮件的可用性,或者注册的电子邮件不能再提交。场景:用户在表单中输入电子邮件,然后系统检查数据库中的电子邮件是否已保存,然后系统触发错误。我试图显示如果“count> 0”的结果,那么输出为true,以便返回对象“{is_notavail:true}”。但是,在模板“is_notavail”中总是返回“false”。奇怪的是,表格颜色是红色的,我也没有提交新的或保存的电子邮件。这些是我的代码。Ionic3的异步定制验证

email.ts(验证器)

import { FormControl } from '@angular/forms'; 
import { UserServiceProvider } from '../../providers/user-service/user-service'; 
import 'rxjs/add/operator/toPromise'; 


export class EmailValidator{ 
    static userService: UserServiceProvider; 
    constructor(userService: UserServiceProvider){ 
     EmailValidator.userService = userService; 
    } 
    checkEmailAvail(control: FormControl){ 
    return EmailValidator.userService.isExist(control.value).toPromise().then(count => { 
     if(count>0){ 
      return {is_notavail: true}; 
     }else return null; 
    }); 

    } 

} 

用户service.ts(服务)

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import 'rxjs/add/operator/map'; 
import { Observable } from "rxjs/Observable"; 
import { User } from "../../models/user.model"; 
import { BehaviorSubject } from "rxjs/BehaviorSubject"; 


@Injectable() 
export class UserServiceProvider { 
    users: Observable<User[]>; 
    private _users: BehaviorSubject<User[]>; 
    private baseUrl: string; 
    private dataStore: { 
    users: User[] 
    }; 
    constructor(public http: Http) { 
    this.baseUrl = 'api/v1/user'; 
    this.dataStore = {users: []}; 
    this._users = <BehaviorSubject<User[]>> new BehaviorSubject([]); 
    this.users = this._users.asObservable(); 
    } 

    isExist(email: string){ 
     return this.http.post(this.baseUrl + '/isexist', {'email': email}).map(data => data.json().data); 
    } 
} 

register.ts(页)

import { Component } from '@angular/core'; 
import { NavController, IonicPage, Loading, AlertController, LoadingController } from 'ionic-angular'; 
import { FormBuilder, FormGroup, Validators, FormControl } from "@angular/forms"; 
import { UserServiceProvider } from '../../providers/user-service/user-service'; 
import { User } from "../../models/user.model"; 
import { PasswordValidator } from '../../validators/password/password'; 
import { EmailValidator } from "../../validators/email/email"; 

@IonicPage() 
@Component({ 
    selector: 'page-register', 
    templateUrl: 'register.html', 
}) 

export class RegisterPage { 
    submitAttempt: boolean = false; 
    registerForm: FormGroup; 
    control: FormControl; 
    _isNotAvail: boolean = false; 
    loading: Loading; 
    user: User = {name: '', email: '', password: ''}; 
    constructor(
    public navCtrl: NavController, 
    private formBuilder: FormBuilder, 
    private userServiceProvider: UserServiceProvider, 
    private alertCtrl: AlertController, 
    private loadingCtrl: LoadingController) { 

    this.registerForm = this.formBuilder.group({ 
     name: ['', Validators.compose([Validators.required])], 
     email: ['', Validators.compose([Validators.required, Validators.email, (new EmailValidator(this.userServiceProvider)).checkEmailAvail])], 
     password: ['', Validators.compose([Validators.required, Validators.minLength(8)])], 
     confPassword: ['', Validators.compose([Validators.required])] 
    }, { 
     validator: PasswordValidator.confPassword('password', 'confPassword') 
    }); 

    } 
} 

register.html

 <ion-item *ngIf="registerForm.get('email').errors && registerForm.get('email').dirty"> 
     <p *ngIf="registerForm.get('email').hasError('required')">Email harus diisi.</p> 
     <p *ngIf="registerForm.get('email').hasError('email')">Email tidak sesuai format.</p> 
     <p *ngIf="registerForm.get('email').hasError('is_notavail')">Email sudah terdaftar.</p> 
    </ion-item> 

回答

1

有Validator和AsyncValidators。如果您向服务器发出请求,则应将其设置为AsyncValidator。要做到这一点,请在第三个参数中的数组中提供验证器。我

email: ['', [Validators.required, Validators.email], [new EmailValidator(this.userServiceProvider).checkEmailAvail]], 

同样在为EmailValidator构造注意到你设置userServiceProvider作为为EmailValidator静态属性。我假设你这样做是因为userServiceProvider在checkEmailAvail验证器函数运行时未定义。这是因为它在调用者的范围内运行。使userServiceProvider成为实例属性(而不是静态属性)并像这样传递函数 -

var emailValidator = new EmailValidator(this.userServiceProvider); 

email: ['', [Validators.required, Validators.email], [emailValidator.checkEmailAvail.bind(emailValidator)]], 
+0

谢谢。问题解决了。我在下面添加评论来阐述这个问题 –

0

谢谢Micah。我深入解释我的问题。其实,有两个错误。

首先我是在第二PARAM代替第三PARAM错放AsyncValidation,你修复我的代码,这是正确的:

let emailValidator = new EmailValidator(this.userService); 
this.registerForm = this.formBuilder.group({ 
    name: ['', Validators.compose([Validators.required])], 
    email: ['', Validators.compose([Validators.required, Validators.email]), emailValidator.checkEmailAvail.bind(emailValidator)], 
    password: ['', Validators.compose([Validators.required, Validators.minLength(8)])], 
    confPassword: ['', Validators.compose([Validators.required])] 
}, { 
    validator: PasswordValidator.confPassword('password', 'confPassword') 
}); 

第二个我的验证应该是承诺,使用解决

import { FormControl } from '@angular/forms'; 
import { UserServiceProvider } from '../../providers/user-service/user-service'; 

export class EmailValidator{ 
    static userService: UserServiceProvider; 
    constructor(userService: UserServiceProvider){ 
     EmailValidator.userService = userService; 
    } 
    checkEmailAvail(control: FormControl){ 
    return new Promise (resolve => { 
      EmailValidator.userService.isExist(control.value).subscribe(count => { 
       if(count>0){     
        return resolve({is_notavail: true}); 
       }else { 
       return resolve(null); 
       } 

    }) 
    }) 
} 
}