Angular Custom Async Validator 保持挂起状态
Posted
技术标签:
【中文标题】Angular Custom Async Validator 保持挂起状态【英文标题】:Angular Custom Async Validator stays in pending state 【发布时间】:2018-03-29 12:41:22 【问题描述】:我有一个自定义验证器,用于验证用户的电子邮件是否唯一。
我在 *** 和互联网上搜索过相关主题,但没有任何帮助
当我在表单中提供输入(发送请求)时,请求保持在挂起状态并且不会解析。
我已经在 postman 中测试了后端,它按预期工作,问题出在客户端或角度方面。
验证函数如下:
emailUniqueValidator (control: AbstractControl): Promise<[key: string]: any> | Observable<[key: string]: any>
return new Promise((resolve, reject) =>
this.userService.checkEmailUnique(control.value).subscribe((response: Response) =>
const body = response.json();
if (body.found === false)
resolve(null); // email is unique
else
reject(emailUniqueValidator: true); // email is not unique
);
);
当我更改表单控件的值时,挂起的类会出现,但它会永远存在而不是得到解决。
我的邮件表单控件如下:
'email': new FormControl('', [
Validators.required,
Validators.email
], this.emailUniqueValidator.bind(this)
),
我的用户服务如下:
checkEmailUnique (email: string): Observable<Response>
return this.http.post('http://localhost:3000/user/email', email, withCredentials: true );
为什么验证者没有及时解决并永远处于等待状态?
编辑:
以下代码可以很好地从服务中获取价值,我已经通过将响应记录到控制台来检查它。
如果电子邮件不存在于数据库中,则解决得很好,但如果电子邮件已经存在,则会引发错误并且状态保持挂起。
return new Promise((resolve, reject) =>
this.userService.checkEmailUnique(control.value).subscribe((response: Response) =>
console.log(response);
response.json().found ? reject(emailUniqueValidator: true) : resolve(null);
, (error: any) => reject(emailUniqueValidator: true));
);
【问题讨论】:
见github.com/angular/angular/issues/13200 有你的组件 ChangeDetectionStrategy.OnPush 吗?emailUniqueValidator (control: AbstractControl): Promise<[key: string]: any> | Observable<[key: string]: any> return this.userService.checkEmailUnique(control.value).pipe( debounceTime(500), distinctUntilChanged(), map(value => value.body.found ? emailUniqueValidator: true : null) );
这个代码对我来说很好用@Eldar
【参考方案1】:
你为什么要通过承诺来包裹可观察到的头痛?试试这样:
emailUniqueValidator (control: AbstractControl): Observable<[key: string]: any>
return this.userService.checkEmailUnique(control.value)
.map(r => r.json())
.map(r => (r.found) ? emailUniqueValidator: true : null);
【讨论】:
我试过你的代码,但是状态仍然是pending,你能告诉为什么会这样吗? 你应该使用 do() 操作符来调试,看看是否有任何东西可以通过,这应该可以工作,有些问题在其他地方。【参考方案2】:observable 永远不会完成。
尝试在末尾添加.first()
。
emailUniqueValidator (control: AbstractControl): Observable<[key: string]: any>
return this.userService.checkEmailUnique(control.value)
.map(r => r.json())
.map(r => (r.found) ? emailUniqueValidator: true : null)
.first();
【讨论】:
较新的 rxjs 版本如下所示:this.userService.checkEmailUnique(control.value).pipe(map(r => r.json()), take(1))
省略了一些细节以保持可读性,因为代码格式化选项在 cmets 中显然是有限的。【参考方案3】:
我遇到了同样的问题。我删除了changeDetection: ChangeDetectionStrategy.OnPush
,它起作用了。一个例子is here。
【讨论】:
【参考方案4】:确保您的“状态代码来自”服务在任何情况下都是 200
var user = _appRepository.GetUserByUserName(username);
if (user != null)
return Ok(user );
return Ok();
这是来自 asp.net 核心 api。当用户不可用时发送空Ok()
。如果角度捕获 404 或 400,则始终显示待处理。
export function uniqueUsernameValidator(userService: UserService): AsyncValidatorFn
return (c: AbstractControl): Observable< [key: string]: any | null> =>
return userService.getUserByUsername(c.value).pipe(
map(users =>
console.log(users)
if (users)
return 'unique': true;
else
return null
)
)
;
【讨论】:
以上是关于Angular Custom Async Validator 保持挂起状态的主要内容,如果未能解决你的问题,请参考以下文章
测试 Angular 2 应用程序中的“CUSTOM_ELEMENTS_SCHEMA”错误
angular 2 custom sort pipe 请帮帮我
如何通过新的 @angular/cli v7 angular.json 或 custom-webpack.config.js 添加额外的 postcss 插件?