在填充组件变量之前调用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};
}));
}
}

如果我试图将用户名更改为已被另一个用户使用,但出现错误,一切都会正常进行。此外,如果在这之后我将其更改为原始用户名,它也可以正常工作,并且不会发送验证请求。

我的this.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:我在ngOnInit中加载this.originUser后添加this.editForm.get('username').updateValueAndValidity();,解决了如何在表单加载时不出错的问题,但在加载表单时仍然会发送不必要的验证请求。

所以解决方案非常简单将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({});
}

最新更新