【问题标题】:How to reset validation error without resetting form in angular?如何在不以角度重置表单的情况下重置验证错误?
【发布时间】:2019-09-10 14:32:40
【问题描述】:

我有一个角度模板驱动的表单。我想重置所有验证错误并使其保持不变而不重置表单。 如何以角度做到这一点? 我试过以下方法

onAdd(form: NgForm) {

form.form.markAsPristine();
form.form.markAsUntouched();

}

但这不起作用。

链接:- https://stackblitz.com/edit/angular-ezixd4

当前行为:- 当我单击提交空表单时,所有字段都标记为错误,当我单击add 时,它会添加字段,但上述功能不会删除错误消息。

预期行为:- 当我单击提交空表单时,所有字段都标记为错误,当我单击 add 时,它会添加该字段,它应该删除表单上(或添加的文件中)的错误消息。

在此表单中,我正在使用添加按钮添加输入字段,并且我想在用户有机会与表单交互之前清除所有错误消息。

【问题讨论】:

  • @ViewChild()试试这个,你会发现更多关于给定link的信息
  • 因此,如果您的表单无效(由于控件中的无效值)并且您将其设为原始但未删除无效值,那么您的表单是否仍然无效。
  • 我试过@ViewChild(),但还是不行。
  • @xyz 是的,但这就是为什么我想让它保持不变,如果用户再次点击提交时使用无效值,错误将再次出现。
  • 我想要这种行为的真正原因是我通过add button动态添加输入字段,因为新添加的输入字段将为空,然后在用户有机会交互之前显示错误用它。

标签: angular forms


【解决方案1】:

使用 Angular Material,您需要定义 FormGroupDirective 以及 FormGroupFormControl

@ViewChild(FormGroupDirective) formGroupDirective: FormGroupDirective;

import { FormGroup, FormControl, FormGroupDirective } from '@angular/forms';

在 onSubmit 方法中使用响应式表单重置重置 FormGroupDirective

this.formGroupDirective.resetForm();
<br>
this.form.reset();

如果上述FormGroupDirective重置不起作用,请尝试超时0秒

setTimeout(() => this.formGroupDirective.resetForm(), 0);

【讨论】:

  • 这应该被标记为答案,因为它似乎是唯一的解决方案
【解决方案2】:

我必须这样做,设置一个超时,以便在单击按钮之前的模糊事件在单击取消按钮后不会得到处理:

let timeout = setTimeout(function() {
  Object.keys(originalValues).forEach(controlName => {
    let control =that.getControl(controlName);
    control.setValue(originalValues[controlName]);
    control.markAsUntouched();
    control.setErrors(null);
    control.markAsPristine();
  });
  this.setControlState(formName);
  clearTimeout(timeout);
}, 10);

【讨论】:

    【解决方案3】:

    这终于对我有用了:

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

    【讨论】:

    • 适用于 Angular 12 .....不会重置值,而只会重置验证..kudos
    【解决方案4】:
     resetForm() {
        this.myFormGroup.reset();
        this.myFormGroup.setErrors(null); // could be removed
        this.myFormGroup.updateValueAndValidity();
      } 
    

    【讨论】:

      【解决方案5】:

      确保表单部分内没有按钮。 Addnew 按钮应该在表单之外。

      【讨论】:

      • 请查看此答案以使用英语。
      【解决方案6】:

      你可以用更通用的方式来做:

      reset(formGroup: FormGroup) {
         Object.keys(formGroup.controls).forEach(
            field => {
               formGroup.get(field).setErrors(null);
            }
          );
      }
      ...
      this.reset(yourForm);
      ...
      

      【讨论】:

        【解决方案7】:

        mat-input-invalid 类部分取决于表单的submitted 状态。因此,当您提交表单时,submitted 属性将切换为 true。 markAsPristine()markAsUntouched() 确实 not 重置 submitted 标志,因此错误仍然显示。我看到了两种可能性。一个又快又脏,当我测试 似乎 在你的情况下工作。我不能保证它在所有情况下都可以,但是您可以尝试一下,看看它是否会起作用。也就是说,您调用resetForm(),它确实重置了submitted 属性。但是,是的,您希望保留设置的值。所以,我们在重置中传递表单当前状态的值:

        onAdd(form: NgForm) {
          this.specification.push(++this.num);
          form.resetForm(form.value);  
        }
        

        DEMO

        所以这是一种肮脏的方式,一种更受控制的方式是使用ErrorStateMatcher,这也在docs 中提到。有了它,您可以选择何时显示错误消息。

        【讨论】:

        • 是的,这是有道理的,我实际上想在用户有机会与之交互之前从新添加的字段中删除错误。
        【解决方案8】:

        您可以遍历每个必填字段并调用它们的 setErrors 方法,同时将 null 传递给它们:

        YOUR_FORM.controls.YOUR_FIELD_NAME.setErrors(null);
        

        例如,当您有 usernamepassword 字段时:

        this.loginForm.controls.username.setErrors(null);
        this.loginForm.controls.password.setErrors(null);
        

        希望这会有所帮助!

        【讨论】:

        • 我相信他只是在显示错误并阻止表单被触摸时提交。如果他将表单标记为原始且未触及,那么他的逻辑应该确实有效。
        • 感谢您的回复,但它完全消除了错误,如果用户仍然不与表单交互,我想重新出现错误,但是从上述方法它完全消除了错误并允许要提交的表单。
        • 去掉所有错误后你的表单真的可以提交吗?当我再次提交表单时,我的表单再次出现错误,因为在我的提交侦听器中检查了表单属性无效是真还是假。表单验证和字段值实际上并没有被删除,而只是错误消息。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-04
        • 2019-07-14
        相关资源
        最近更新 更多