angular - 在填充组件变量之前调用 Reactive Forms 异步验证器
问题描述
所以我想要做的是验证用户名是否已经在我的用户编辑表单中。这是我的表格:
editForm= new FormGroup({
username: new FormControl('', [Validators.required, Validators.maxLength(60)], this.validateUser.bind(this)),
fullName: new FormControl('', Validators.maxLength(60)),
email: new FormControl('', Validators.maxLength(60)),
phoneNumber: new FormControl('', Validators.maxLength(60)),
}, { updateOn: "blur"});
在我的验证器中,我通过将原始用户名与从服务器加载的用户信息的变量进行比较来检查在发送验证请求之前是否更改了原始用户名:
validateUser(control: FormControl): Observable<ValidationErrors | null> {
if(control.value != this.originUser.username){
return this.userService.validateUsername(control.value).pipe(map(res => {
return res['valid'] ? null : { invalidUsername: true};
}));
}
}
如果我尝试将用户名更改为已被其他用户使用并且我收到错误消息,则一切正常。此外,如果在此之后我将其更改为原始用户名,它也可以正常工作并且不会发送验证请求。
Mythis.originUser
被填充,ngOnInit
这发生在第一次在表单初始化时调用验证器之后,所以我仍然看到发送了带有原始用户名的验证请求,并在使用原始用户名加载表单时出现错误。
ngOnInit() {
this.userService.getOne(this.id).subscribe(user =>{
this.editForm.patchValue({
username: user.username,
fullName: user.fullName,
email: user.email,
phoneNumber:user.phoneNumber
});
this.originUser = user;
});
}
}
当我打开“编辑用户”页面时第一次调用验证器时,我无法弄清楚如何不发送验证请求的逻辑
UPD:
我想出了如何通过this.editForm.get('username').updateValueAndValidity();
在我加载后添加而不在表单加载时出错this.originUser
,ngOnInit
但在表单加载时仍会发送不必要的验证请求。
解决方案
所以解决方案非常简单添加control.dirty
到验证器条件,因此如果用户没有更改输入,则永远不会发送请求
validateUsername(control: FormControl): Observable<ValidationErrors | null> {
if(control.value != this.originUser.username && control.dirty){
return this.userService.validateUsername(control.value).pipe(map(res => {
return res['valid'] ? null : { invalidUsername: true};
}));
} else return of({});
}
推荐阅读
- mongodb - MongoTimeoutError:服务器选择在 30000 毫秒后超时
- ubuntu - 由于配置错误,无法启动 nginx
- wordpress - Facebook Pixel 不适用于移动浏览器(但适用于桌面浏览器)
- arabic - Indesign中的希伯来语或阿拉伯语排版问题
- python - 无法在 Django 上使用 SSL 连接到 PostgreSQL
- c# - 使用替代解决方案提高循环性能
- sharepoint - Sharepoint Online - UserId.NameId
- microsoft-graph-api - 如何使用 Microsoft 图形 API 以编程方式设置团队图片?
- r - 将 3D 数组转换为数据帧列表
- c# - 防止通过鼠标拖动子窗体