Ionic3

时间:2017-09-06 14:50:02

标签: angular validation asynchronous ionic3

我想检查电子邮件的可用性,或者无法再提交已注册的电子邮件。方案:用户在表单中键入电子邮件然后系统检查数据库中是否已保存电子邮件,然后系统触发错误。我试图显示结果,如果“count> 0”,则输出为true,以便返回对象“{is_notavail:true}”。但是,在模板“is_notavail”中始终返回“false”。奇怪的是,表单颜色是红色的我既不提交新的也不保存电子邮件。这些是我的代码。

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;
    });

    }

}

user-service.ts(service)

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(pages)

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>

2 个答案:

答案 0 :(得分:2)

有Validators和AsyncValidators。如果您向服务器发出请求,则应将其设为AsyncValidator。为此,请在第3个参数的数组中提供验证器。

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

我还注意到在EmailValidator构造函数中,您将userServiceProvider设置为EmailValidator上的静态属性。我假设你这样做是因为当checkEmailAvail验证器函数运行时userServiceProvider未定义。这是因为它与调用者的范围一起运行。使userServiceProvider成为实例属性(而不是静态属性)并传递函数,如this-

var emailValidator = new EmailValidator(this.userServiceProvider);

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

答案 1 :(得分:1)

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

第一个我错了把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')
});

第二个我的验证器应该是promise并使用resolve

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);
                }

    })
    })
}
}