【问题标题】:Angular Reactive forms : how to reset form state and keep values after submitAngular Reactive forms:如何在提交后重置表单状态并保留值
【发布时间】:2017-10-01 06:11:57
【问题描述】:

以 Angular 反应形式。提交成功后如何只重置表单的状态

流程如下:

  • 根据服务结果创建表单和setValue
  • 修改值并提交表单
  • 如果表单正确提交到服务,则重置并保留值

如何保持修改后的值并将表单重置为其原始状态。

form.reset() 只是清空表单。但如果我不调用它,状态不会重置,例如我的验证取决于表单状态类(原始、脏、有效等)仍然存在。

【问题讨论】:

  • 我通常会创建一个类似 initForm 的方法,我会在 ngInit 上调用它,并在提交表单后再次调用

标签: angular typescript angular-reactive-forms


【解决方案1】:

@smnbbrv 的解决方案效果很好。

您还可以将实际表单值提供给 reset() 方法。

鉴于myReactiveForm 在您的组件中是一个响应式表单。成功提交表单后(例如通过调用服务),您可以执行以下操作:

this.myReactiveForm.reset(this.myReactiveForm.value);

它将重置表单并将“新”表单值设置为您的表单值。

这个方法可以在英雄之旅示例Official Angular.io doc中看到

【讨论】:

  • 这是一个 hack :D 但是,我必须承认它应该可以工作 ;)
  • 是的!我们可以通过阅读 Angular 文档找到惊人的解决方案。这些家伙真是……太棒了!
  • 好吧,自从 angular2 beta 读了四遍之后,我已经厌倦了,所以我会把它留给喜欢它的人 :) 我实际上并不认为这是一个好的解决方案,因为它会不必要地重写所有表单值,并且可能会导致大型表单出现性能问题。
  • 试过了,这个解决方案不起作用。因为响应式表单会立即从输入字段接收最新值,所以传递给“reset”方法的“this.myReactiveForm.value”不会反映表单的先前状态,而是表单上的最新值。因此,这种复位方式会导致无操作。此解决方案下的表单保持不变,而不是按预期恢复/重置为先前的状态。
【解决方案2】:

这很容易:

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

这将重置表单元数据并且表单再次原始

【讨论】:

  • 这是否也删除了验证部分?
  • @sireeshaj 完全取决于您的意思。如果您使用角度材质控件,请参阅我的答案。
【解决方案3】:

@angular/components (material) 用户注意事项

如果您使用有角度的材质控件,则会增加复杂性,使用mat-error 来显示您的错误。此类错误会根据ErrorStateMatcher 的结果显示(除了您可能已应用的任何*ngIf)。

如果满足以下条件,default ErrorStateMatcher 将显示错误:

isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean 
{
   return !!(control && control.invalid && (control.touched || (form && form.submitted)));
}

也就是说,如果表单曾经被提交并且控件变得无效(根据验证规则),那么将显示错误。这通常不是您想要的(特别是如果您正在阅读此问题!)。

查看源代码 - 除非您在 ngForm 指令(而不是 FormGroup 对象)上调用 resetForm,否则无法设置 submitted = false。将状态设置为原始或未触及不会重置为 false。

如果您使用的是mat-error,如果这是一个问题,您可能会发现为自定义逻辑创建自己的 ErrorStateMatcher(简单接口)会更容易。

另请注意,ErrorStateMatcher 仅在角度材料中 - 而不是标准角度形式的一部分。

【讨论】:

  • tldr:从 ngForm 指令中获取模板变量并将其传递给您的重置方法。然后拨打resetForm就可以了。
  • 正如这个答案指出的那样,在这种情况下(验证器将在使用FormGroup#reset() 恢复表单时在表单上显示错误,使用模板变量<form #login="ngForm" ... > 并将登录模板变量传递给你的(ngSubmit)="submit(login)" 函数并在其上调用resetForm() 。或者不必依赖提交事件,使用@ViewChild('login') private _loginNgForm: NgForm; 然后this._loginNgForm.resetForm();
【解决方案4】:

2020 年 4 月 6 日: Ionic 5+ 和 Angular 9+

只有一行。即this.form.reset();

重置 FormGroup,将所有后代标记为原始和未触及,并将所有后代的值设置为 null。

 form: FormGroup;

 constructor(private formBuilder: FormBuilder, ) { }

  resetTheForm(): void {
    this.form.reset();
  }

【讨论】:

    【解决方案5】:

    对于使用 Angular 7 时对我有用的反应式表单:使用模板驱动的表单并像这样通过表单提交处理程序传递它

    // component.html
     <form #f="ngForm" [formGroup]="form" (ngSubmit)="onSubmit(f)" novalidate>
     ....
    </form>
    
    
    // component.ts
    
    onSubmit(form: NgForm) {
    
    // reset form here
     form.form.markAsPristine();
     form.resetForm();
    }
    
    

    它会将表单和提交状态重置为默认值。

    【讨论】:

      【解决方案6】:

      添加另一个答案,如果您的表单中有禁用输入,请使用 getRawValue() 作为 ngForm.resetForm() 的参数。查看示例:

      在 HTML 中:

      <form
        (ngSubmit)="formSubmit(myForm)"
        #myForm="ngForm"
      >
          ...
      </form>
      

      在 .TS 中:

      formSubmit(myForm: NgForm) {
         myForm.resetForm(myForm.form.getRawValue());
      }
      

      【讨论】:

        【解决方案7】:

        有时this.myForm.reset(this.myForm.value); 可能不会重置为初始值 所以最好创建一个单独的函数来初始化表单并在 ngOnInit() 和调用之前调用它this.myForm.reset(this.myForm.value);

        ngOnInit(){
          myFormValues();
        }
        
        myFormValues() {
          this.myForm= this.fb.group({
              id: ['', Validators.required],
              name: ['', Validators.required],
            });
        }
        
        submitForm() {
          // save data
          myFormValues();
          this.myForm.reset(this.myForm.value)
        }
        

        【讨论】:

          【解决方案8】:

          我使用 patch 值 来清除响应式表单控件。它对我有用。请尝试以下代码。

          onClear() {
             this.formGroup.patchValue({
               fieldName: ''
             });
          }
          

          【讨论】:

            猜你喜欢
            • 2022-01-25
            • 2019-06-22
            • 2021-01-13
            • 2021-11-13
            • 1970-01-01
            • 2019-04-10
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多