Html Angular 5 FormGroup 重置不会重置验证器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48216330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 15:02:55  来源:igfitidea点击:

Angular 5 FormGroup reset doesn't reset validators

htmlangulartypescriptangular-materialangular-reactive-forms

提问by efarley

I have a form on my page and when I call FormGroup.reset()it sets the forms class to ng-pristine ng-untouchedbut FormControl.hasError(...)still returns truthy. What am I doing wrong here?

我的页面上有一个表单,当我调用FormGroup.reset()它时,将表单类设置为ng-pristine ng-untouchedFormControl.hasError(...)仍然返回真实。我在这里做错了什么?

Template

模板

<form [formGroup]="myForm" (ngSubmit)="submitForm(myForm)">
  <mat-form-field>
    <input matInput formControlName="email" />
    <mat-error *ngIf="email.hasError('required')">
      Email is a required feild
    </mat-error>
  </mat-form-field>
  <mat-form-field>
    <input matInput type="password" formControlName="password" />
    <mat-error *ngIf="password.hasError('required')">
      Password is a required feild
    </mat-error>
  </mat-form-field>
  <button type="submit">Login</button>
</form>

Component

成分

export class MyComponent {
  private myForm: FormGroup;
  private email: FormControl = new FormContorl('', Validators.required);
  private password: FormControl = new FormControl('', Validators.required);

  constructor(
    private formBuilder: FormBuilder
  ) {
    this.myForm = formBuilder.group({
      email: this.email,
      password: this.password
    });
  }

  private submitForm(formData: any): void {
    this.myForm.reset();
  }
}

Plunker

普朗克

http://embed.plnkr.co/Hlivn4/

http://embed.plnkr.co/Hlivn4/

回答by Harry Ninh

It (FormGroup) behaves correctly. Your form requires username and password, thus when you reset the form it should be invalid (i.e. form with no username/password is not valid).

它 ( FormGroup) 行为正确。您的表单需要用户名和密码,因此当您重置表单时,它应该是无效的(即没有用户名/密码的表单无效)。

If I understand correctly, your issue here is why the red errors are not there at the first time you load the page (where the form is ALSO invalid) but pop up when you click the button. This issue is particularly prominent when you're using Material.

如果我理解正确,您的问题是为什么在您第一次加载页面(表单也无效)时没有出现红色错误,但在您单击按钮时会弹出。当您使用 Material 时,这个问题尤其突出。

AFAIK, <mat-error>check the validity of FormGroupDirective, not FormGroup, and resetting FormGroupdoes not reset FormGroupDirective. It's a bit inconvenient, but to clear <mat-error>you would need to reset FormGroupDirectiveas well.

AFAIK,<mat-error>检查 的有效性FormGroupDirective,不是FormGroup,并且重置FormGroup不会重置FormGroupDirective。这有点不方便,但要清除<mat-error>您还需要重置FormGroupDirective

To do that, in your template, define a variable as such:

为此,在您的模板中,定义一个变量:

<form [formGroup]="myForm" #formDirective="ngForm" 
  (ngSubmit)="submitForm(myForm, formDirective)">

And in your component class, call formDirective.resetForm():

在您的组件类中,调用formDirective.resetForm()

private submitForm(formData: any, formDirective: FormGroupDirective): void {
    formDirective.resetForm();
    this.myForm.reset();
}

GitHub issue: https://github.com/angular/material2/issues/4190

GitHub 问题:https: //github.com/angular/material2/issues/4190

回答by Savio Rodrigues

After reading the comments this is the correct approach

阅读评论后,这是正确的方法

// you can put this method in a module and reuse it as needed
resetForm(form: FormGroup) {

    form.reset();

    Object.keys(form.controls).forEach(key => {
      form.get(key).setErrors(null) ;
    });
}

There was no need to call form.clearValidators()

没有必要打电话 form.clearValidators()

回答by Maximillion Bartango

In addition to Harry Ninh's solution, if you'd like to access the formDirective in your component without having to select a form button, then:

除了 Harry Ninh 的解决方案,如果您想访问组件中的 formDirective 而不必选择表单按钮,则:

Template:

模板:

<form 
  ...
  #formDirective="ngForm" 
>

Component:

成分:

import { ViewChild, ... } from '@angular/core';
import { NgForm, ... } from '@angular/forms';

export class MyComponent {
 ...
 @ViewChild('formDirective') private formDirective: NgForm;

  constructor(... )

  private someFunction(): void { 
    ...
    formDirective.resetForm();
  }
}

回答by Henri Fournier

I found that after calling resetForm() and reset(), submitted was not being reset and remained as true, causing error messages to display. This solution worked for me. I found it while looking for a solution to calling select() and focus() on an input tag, which also wasn't working as expected. Just wrap your lines in a setTimeout(). I think setTimeout is forcing Angular to detect changes, but I could be wrong. It's a bit of a hack, but does the trick.

我发现在调用 resetForm() 和 reset() 之后,提交没有被重置并保持为真,导致显示错误消息。这个解决方案对我有用。我在寻找在输入标签上调用 select() 和 focus() 的解决方案时发现了它,这也没有按预期工作。只需将您的行包装在 setTimeout() 中。我认为 setTimeout 迫使 Angular 检测变化,但我可能是错的。这有点像黑客,但可以解决问题。

<form [formGroup]="myFormGroup" #myForm="ngForm">
    …
    <button mat-raised-button (click)="submitForm()">
</form>
submitForm() { 
    …
    setTimeout(() => {
        this.myForm.resetForm();
        this.myFormGroup.reset();
    }, 0);
}

回答by Sayan Samanta

The below solution works for me when trying to reset specific form controller in form group -

尝试重置表单组中的特定表单控制器时,以下解决方案对我有用 -

 this.myForm.get('formCtrlName').reset();
 this.myForm.get('formCtrlName').setValidators([Validators.required, Validators.maxLength(45), Validators.minLength(4), Validators.pattern(environment.USER_NAME_REGEX)]);
 this.myForm.get('formCtrlName').updateValueAndValidity();

回答by mpro

Nothing from above worked for me (Angular 7.2, Angular Material 7.3.7).

以上没有对我有用(Angular 7.2,Angular Material 7.3.7)。

Try to pass with submit method an event on view:

尝试使用 submit 方法传递一个事件:

<form [formGroup]="group" (ngSubmit)="onSubmit($event)">
    <!-- your form here -->
</form>

Then use it to reset currentTargetand your form afterwards:

然后用它来重置currentTarget和你的表格之后:

public onSubmit(event): void {
  // your code here
  event.currentTarget.reset()
  this.group.reset()
}

回答by Andreas Griechihin

Simple fix: use button with type="reset"and function submitForm()together

简单修复:将按钮与type="reset"功能submitForm()一起使用

<form [formGroup]="MyForm" (ngSubmit)="submitForm()">
  <input formControlName="Name">
  <mat-error>  
    <span *ngIf="!tunersForm.get('Name').value && tunersForm.get('Name').touched"></span>  
  </mat-error>
  <button type="reset" [disabled]="!MyForm.valid" (click)="submitForm()">Save</button>
</form>

回答by Janith

I had no luck with resetting the form directive. But You can also change the input state to pending to do that as well.

我没有重置表单指令的运气。但是您也可以将输入状态更改为挂起来执行此操作。

this.myForm.get("email").reset();
this.myForm.get("password").reset();

回答by GoForth

To anyone whom this may help, I am running Angular 9.1.9 and I didn't want to reset the form/controls just the overall validity of the form so I just ran:

对于这可能有帮助的任何人,我正在运行 Angular 9.1.9,我不想重置表单/控件只是表单的整体有效性,所以我只是运行:

this.registerForm.setErrors(null);

...where registerForm: FormGroupand that reset the form errors, leading to:

...在哪里registerForm: FormGroup重置表单错误,导致:

this.registerForm.valid

...returning true.

……回来了true

The same can be done for controls:

对控件也可以这样做:

this.registerForm.get('email').setErrors(null)

As soon as the form is touched, these errors are re-evaluated anyway so if that's not good enough, you may need to have a boolean flag to further pin-down exactly when you want to start showing/hiding error UI.

一旦触摸表单,无论如何都会重新评估这些错误,因此如果这还不够好,您可能需要一个布尔标志来进一步确定何时开始显示/隐藏错误 UI。

I did not need to touch the directive in my case.

在我的情况下,我不需要触及指令。

回答by prisar

I was also having the same set of problems. My problem was that i was using mat-form-fieldand formGroup. After resetting the form submittedflag was not resetting.

我也遇到了同样的问题。我的问题是我正在使用mat-form-fieldformGroup。重置表单submitted标志后没有重置。

So, the solution that worked for me is, putting a directive of ngFormalong with formGroupand passing onSubmit(form). Added @ViewChild('form') form;in component and then I used this.form.resetForm();

所以,对我有用的解决方案是,放置一个指令ngFormwithformGroup并传递onSubmit(form). 添加 @ViewChild('form') form;到组件中,然后我使用 this.form.resetForm();