Angular12 表单验证成功后mat-input仍为无效状态如何解决
问题原因
- Angular异步校验器的规则为:校验通过时返回
null,校验失败时返回携带错误标识的ValidationErrors对象。你当前的matchCurrentPassword逻辑中,密码匹配成功(x.isExecute = true)时返回了{matches: true},Angular会判定该字段存在错误,因此始终标记为无效状态。 - 校验器返回类型定义错误,正确返回类型应为
Observable<ValidationErrors | null>,而非Observable<ValidationErrors | ValidationErrors>。 - 模板错误判断逻辑与校验返回逻辑冲突:你在模板中判断
currentPassword.errors?.matches==false才展示不匹配提示,但实际校验逻辑中匹配成功时返回的非null对象会导致字段状态异常,只是错误提示刚好符合你的预期。
解决方案
第一步:修改matchCurrentPassword异步校验器的返回逻辑,校验通过时返回null,校验失败时返回错误对象:
matchCurrentPassword = ( control: AbstractControl ): Observable<ValidationErrors | null> => { return this.userService.matchCurrentPassword(localStorage.getItem("userId"), control.value) .pipe( tap(x => console.log("response:", x)), map((x: any) => { // 密码匹配成功返回null,标识校验通过;匹配失败返回错误对象 return x.isExecute ? null : { matches: true }; }) ) }
第二步:同步修改模板中的错误提示判断逻辑,匹配失败时errors下存在matches属性,直接判断即可:
<mat-error *ngIf="currentPassword.errors?.matches">Doesn't match</mat-error>
修改完成后,密码匹配成功时字段会自动切换为valid状态,整个表单的有效性也会同步更新。
内容的提问来源于stack exchange,提问作者Valkyrie_30
相关产品推荐
相关产品推荐

