在填充组件变量之前调用 Reactive Forms 异步验证器
Reactive Forms async validator is called before component variables are populated
所以我要做的是验证用户名是否已在我的用户编辑表单中被使用。
这是我的表格:
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;
});
}
}
打开"Edit user"页面
第一次调用validator时,我无法弄清楚如何不发送验证请求的逻辑
更新:
我想出了如何通过在 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({});
}
所以我要做的是验证用户名是否已在我的用户编辑表单中被使用。 这是我的表格:
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;
});
}
}
打开"Edit user"页面
第一次调用validator时,我无法弄清楚如何不发送验证请求的逻辑更新:
我想出了如何通过在 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({});
}