我已经为我的注册表单构建了一个验证服务,其中一个静态方法是通过调用我的API来检查输入的电子邮件是否可用:
static emailAvailable(control){
let injector = ReflectiveInjector.resolveAndCreate([HTTP_PROVIDERS]);
let http = injector.get(Http);
let valid = "E-mail is available";
http.post('https://secretapi.com/email', JSON.stringify({ email: control.value }))
.map((res: Response) => res.json())
.subscribe(function(result){
if(result.success){
valid = result.success; //The console.log on the line below is correct, the one at the bottom of the script never changes.
console.log(valid);
return null; //Doesn't do anything?
}else{
valid = result.error; //The console.log on the line below is correct, the one at the bottom of the script never changes.
console.log(valid);
return { 'invalidEmailAddress': true }; //Doesn't do anything, just like the return above
}
});
console.log(valid); //Output always "E-mail is available"
}
当电子邮件可用时,它应该向表单验证器返回“null”。底部的最后一个console.log应该输出它在订阅调用中收到的消息。这不会发生,我不知道为什么。出于某种原因,订阅调用中发生的所有事情都包含在那里,并且永远不会到达验证器。我应该改变什么?我不知道,现在已经在网上搜索了几个小时。
答案 0 :(得分:0)
您必须从验证码返回Observable
或Promise
:
return http.post('https://secretapi.com/email', ...
console.log(...)
在这里没有任何意义,因为它会在Observable
创建为对象后执行,但不会在ajax
调用之后执行
如果您想在收到回复后输出内容,则必须将其移至subscribe
答案 1 :(得分:0)
所以最后这个website得到了正确答案。同样重要的是要注意Angular2 Form验证器将Async验证器放在第三个(3)参数中,而不是放在第二个(2)参数的数组中。这花了我大约3个小时才弄明白。
function checkEmail(control:Control){
let injector = ReflectiveInjector.resolveAndCreate([HTTP_PROVIDERS]);
let http = injector.get(Http);
return new Observable((obs: any) => {
control
.valueChanges
.debounceTime(400)
.flatMap(value => http.post('https://secretapi.com/email', JSON.stringify({ email: control.value })))
.map((res: Response) => res.json())
.subscribe(
data => {
if(data.success){
obs.next(null);
obs.complete();
} else {
obs.next({ 'invalidEmailAddress': true });
obs.complete();
}
}
);
});
}
验证器应该看起来像这样,第一个验证器检查是否需要,如果它实际上是一个电子邮件地址,最后一个对服务器进行异步调用以查看它是否已经在使用方法:
this.registerForm = this.formBuilder.group({
'email': ['', [Validators.required, ValidationService.emailValidator], ValidationService.emailAvailable],
});