[英]Async Custom Validation at Ionic3
I want to check availability of email or the registered email cannot be submitted any more. 我想查看电子邮件的可用性,或者已注册的电子邮件无法再提交。 The scenario: user types email in form then system checks if in database the email was already saved then system triggers error.
方案:用户在表单中键入电子邮件然后系统检查数据库中是否已保存电子邮件,然后系统触发错误。 I tried to display the result that if "count > 0" then the output is true so that return object "{is_notavail: true}".
我试图显示结果,如果“count> 0”,则输出为true,以便返回对象“{is_notavail:true}”。 However, in template "is_notavail" always return "false".
但是,在模板“is_notavail”中始终返回“false”。 Strangely, form color is red neither I submit new nor saved email.
奇怪的是,表单颜色是红色的我既不提交新的也不保存电子邮件。 These are my codes.
这些是我的代码。
email.ts (validator) 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) 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 (pages) 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 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>
There are Validators and AsyncValidators. 有Validators和AsyncValidators。 If you are making a request to the server you should make this an AsyncValidator.
如果您向服务器发出请求,则应将其设为AsyncValidator。 To do that, provider the validator in an array in the 3rd parameter.
为此,请在第3个参数中的数组中提供验证器。
email: ['', [Validators.required, Validators.email], [new EmailValidator(this.userServiceProvider).checkEmailAvail]],
Also I noticed in the EmailValidator constructor you set the userServiceProvider
as a static property on EmailValidator. 我还注意到在EmailValidator构造函数中,您将
userServiceProvider
设置为EmailValidator上的静态属性。 I assume you are doing this because userServiceProvider
is undefined when the checkEmailAvail validator function runs. 我假设您正在执行此操作,因为在checkEmailAvail验证程序函数运行时未定义
userServiceProvider
。 This is because it's running with the scope of the caller. 这是因为它与调用者的范围一起运行。 Make the userServiceProvider an instance property (instead of a static property) and pass the function like this-
使userServiceProvider成为一个实例属性(而不是静态属性)并传递这样的函数 -
var emailValidator = new EmailValidator(this.userServiceProvider);
. 。
email: ['', [Validators.required, Validators.email], [emailValidator.checkEmailAvail.bind(emailValidator)]],
Thank you Micah. 谢谢弥迦。 I explain my problem in deep.
我深入解释我的问题。 Actually, there are two mistakes.
实际上,有两个错误。
The first I was wrong put AsyncValidation in second param instead of third param, you fix my code, this is the right one: 第一个我错了把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')
});
The second my validator should be promise and uses resolve 第二个我的验证器应该是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);
}
})
})
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.