首页 > 解决方案 > 在填充组件变量之前调用 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.originUserngOnInit但在表单加载时仍会发送不必要的验证请求。

标签: angularangular-reactive-formsangular-validation

解决方案


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

推荐阅读