【问题标题】:Async Custom Validation at Ionic3Ionic 3 中的异步自定义验证
【发布时间】:2018-02-15 03:05:21
【问题描述】:

我想检查电子邮件的可用性或无法再提交已注册的电子邮件。场景:用户在表单中输入电子邮件,然后系统检查数据库中是否已保存电子邮件,然后系统触发错误。我试图显示结果,如果“count > 0”那么输出为真,以便返回对象“{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(服务)

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

  }
}

注册.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>

【问题讨论】:

    标签: angular validation asynchronous ionic3


    【解决方案1】:

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

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

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

    var emailValidator = new EmailValidator(this.userServiceProvider);
    

    .

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

    【讨论】:

    • 谢谢。问题解决了。我在下面添加评论以详细说明问题
    【解决方案2】:

    谢谢你米卡。我深入解释了我的问题。其实有两个错误。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-06
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 1970-01-01
      • 2019-11-09
      相关资源
      最近更新 更多