Angular NgForm:重置精确的表单字段值将使其无效

Angular NgForm:重置精确的表单字段值将使其无效,angular,angular-material,angular-forms,Angular,Angular Material,Angular Forms,我在组件的模板上有一个表单: <form (ngSubmit)="submitLogin(loginForm)" #loginForm="ngForm"> <mat-input-container> <input matInput [placeholder]="'User Name'" ngModel name="username" autofocus required> </mat-input-container> <b

我在组件的模板上有一个表单:

<form (ngSubmit)="submitLogin(loginForm)" #loginForm="ngForm">
  <mat-input-container>
    <input matInput [placeholder]="'User Name'" ngModel name="username" autofocus required>
  </mat-input-container>
  <br>
  <mat-input-container>
    <input matInput [placeholder]="'Password'" ngModel type="password" name="password" required>
  </mat-input-container>
  <br>
  <button [disabled]="loginForm.invalid" mat-raised-button type="submit">
    Login
  </button>
</form>
它的工作原理和登录错误(传递一些随机值)我看到

问题。如何在表单上重新设置精确的fileld,使其真正原始和未被触动?因此,它应该是有效的,而不需要在UI上用红色的“无效”边框标记它


就在
loginForm.controls.password.reset()
之后,我看到
loginForm.controls.password.toucted
false
loginForm.controls.password.pristite
true,但我还看到
loginForm.controls.password.status
为“无效”。如果我破解它并直接将“VALID”值分配给
status
属性,红色无效边框将消失,但如果我聚焦于该字段,它将打破失去焦点无效,然后在没有任何输入的情况下离开。应该有一种合法的方法来重置表单并使其同时生效。

您可以使用
markAs
现有功能

像这样的

this.loginForm.controls.password.reset()
this.loginForm.controls.password.markAsPristine()
this.loginForm.controls.password.markAsUntouched()
this.loginForm.controls.password.updateValueAndValidity()
这些是实际的API函数,当您想要强制执行特定状态,而不想完全依赖于字段状态的角度决定时


检查如何更好地使用
updateValueAndValidity
方法这似乎是一个已知的问题。根据计算错误状态,如下所示:

isInvalid && (isTouched || isSubmitted)
因此,当您提交表单时,
isSubmitted
标志被设置为
true
,从而满足条件,并且您的字段显示为红色。有一些解决方法,如果要重置整个表单,可以使用
resetForm
来代替,但是这里您只想重置一个字段,所以

有一个要使用的


ErrorStateMatcher:

导出类MyErrorStateMatcher实现ErrorStateMatcher{
isErrorState(控件:FormControl | null,形式:FormGroupDirective | NgForm | null):布尔值{
//触摸和无效时显示错误
返回(control.invalid&&control.toucted);
}
}
并在TS中声明ErrorStateMatcher:

matcher=newmyErrorStateMatcher();

似乎有效:

不幸的是,这并不重要,因为(正如我在问题中提到的)已重置的控件已经是原始的、未被触及的。问题处于“无效”状态…我已编辑我的答案,以包含解决问题的附加呼叫。还包括到angular文档的链接,您可以在其中检查iThanks的用法,以获得演示和解释!但失焦事件的失效失效问题仍然存在。我使用了StackBlitz()来证明,只要设置
loginForm.controls.password.setErrors(null)
(与破坏性设置
loginForm.controls.password.status=“VALID”
的方法相同),我就可以轻松实现相同的结果。但我需要在关注此字段时使其无效,然后不做任何更改。我在帖子中建议首先使用
loginForm.controls.password.setErrors(null)
,但注意,重置后该按钮已启用,因为错误已被删除,不再需要密码:),但返回到您的问题,您的意思是想在触摸
时显示错误?是的,通过您上次的更新,问题已经解决,非常感谢!太好了,很高兴听到!我将相应地更新我的答案:)