我有下一个逻辑验证器,我想检查数据,将其发送到服务器。服务器响应良好,但是当我尝试发送用户时,我可以发送表单。谢谢。 // file:email-user-validator.ts
interface IUsernameEmailValidator {
}
function checkUser(control: Control, source: string) : Observable<IUsernameEmailValidator> {
// Manually inject Http
let injector = ReflectiveInjector.resolveAndCreate([HTTP_PROVIDERS]);
let http = injector.get(Http);
let body;
if(source == 'email'){
body = JSON.stringify({ email: control.value })
}else if(source == 'username'){
body = JSON.stringify({ username: control.value });
}
return new Observable((obs: any) =>{
if(!!control.valueChanges){
control
.valueChanges
.debounceTime(400)
.flatMap(value => http.post('/user/check', body))
.subscribe(
value =>{
obs.next(null);
obs.complete();
},
error => {
if(error.status == 500) return;
let msg = error.json().message;
obs.next({ msg: true });
obs.complete();
}
)
}
});
}
export class CustomValidators {
static checkUsername(control: Control) {
checkUser(control, 'username');
}
static checkEmail(control: Control) {
checkUser(control, 'email');
}
}
组件:
//File: main-component.ts
ngOnInit(): any{
this.registerForm = this._formBuilder.group({
'email': ['', Validators.compose([Validators.required, CustomValidators.emailValidator])],
'password': ['', Validators.minLength(8)]
})
}
服务器控制器
check: (req, res) => {
let find = {};
let email = false;
if(req.param('username')){
find.username = req.param('username');
}else if(req.param('email')){
find.email = req.param('email');
email = true;
}
User.findOne(find).exec((err, user) => {
if(err) return res.negotiate(err);
if(user && !email){
return res.status(409).json({message: 'Username taken'});
}else if(user && !!email){
return res.status(409).json({message: 'Email taken'})
}
// not taken
return res.status(200).json({message: !!user});
});
}
答案 0 :(得分:1)
为此,您需要在表单中使用全局异步验证器,因为它适用于电子邮件和密码:
ngOnInit(): any{
this.registerForm = this._formBuilder.group({
'email': ['',
Validators.compose([Validators.required, CustomValidators.emailValidator]),
CustomValidators.checkUser], // <-----
'password': ['', Validators.minLength(8)]
})
}
对于这样的valdidator,您需要返回一个承诺,以便在验证完成时通知成功或失败。在这两种情况下,您都需要解决承诺:如果成功使用null
,否则使用与错误对应的对象。
此外,您可以提供http作为参数,并且您不需要在valueChanges上注册,因为验证程序在每次更新时都会触发。
function createCheckUser(http:Http) {
return function(control: Control) : Promise {
let body = JSON.stringify({ email: control.value })
return new Promise((resolve: any) =>{
http.post('/user/check', body))
.subscribe(
value =>{
// If successful
resolve(null);
// If validation failed
//resolve({email:'The email...'});
},
error => {
resolve({email:'An error occurs'});
}
)
});
};
}
以下是在这种情况下配置验证器的方法:
ngOnInit(): any{
this.registerForm = this._formBuilder.group({
'email': ['',
Validators.compose([Validators.required, CustomValidators.emailValidator]),
CustomValidators.createCheckUser(this.http)], // <-----
'password': ['', Validators.minLength(8)]
})
}
有关更多详细信息,请参阅此文章(部分&#34;字段和#34的异步验证;)