【问题标题】:How to detect changes in a prefilled Angular Reactive Form in Edit Mode如何在编辑模式下检测预填充的 Angular 反应表单中的更改
【发布时间】:2021-12-19 12:08:07
【问题描述】:

我想在编辑模式下检测响应式表单上的更改。 我尝试使用 valueChanges 但问题是当我加载已提交的表单以进行编辑时,它会触发每个预填充控件的事件。 虽然我的要求是仅在用户对表单进行任何更改时触发。 任何人都可以请建议

【问题讨论】:

  • 尝试在开始编辑时使用一些标志来激活 valueChanges 部分(可能在 keyup 和一些 1 或 2 个标志的帮助下......)不确定,你必须提供一些代码才能获得帮助。

标签: html angular typescript frontend angular-reactive-forms


【解决方案1】:

尝试在ngAfterViewInit()方法中订阅valueChanges

export class MyComponent implements AfterViewInit {

  ngAfterViewInit() {
    this.myForm.controls['name'].valueChanges.subscribe(change => {
      console.log(change);
    });
  }

  ... 

【讨论】:

    【解决方案2】:

    使用valueChanges 对您来说是正确的方法。

    我假设您使用setValuepatchValue 来设置预填充值。这两个都作为可选的emitEvent 属性。如果将其设置为false,则不会触发valueChanges。所以....当您设置预填充值时,请使用:

    this.form.setValue({ test: "test" }, { emitEvent: false });
    

    此操作现在不会触发valueChanges

    【讨论】:

    • 实际上这些值被加载为默认值。前任。用户名:[someValue, [Validators.Required]
    • 如果是这种情况 valueChanges 将不会触发,因为如果它是 初始值,则表单值没有改变。你确定你以前没有建立表格吗?请提供minimal reproducible example
    【解决方案3】:

    所有FormControl 对象都具有markAsUntouched()markAsPristine() 等方法,因此,根据@uminder 的指示,在ngAfterViewInit 的触发之后或直接在之后将整个表单设置为pristine您的表单已初始化您可以简单地遍历所有FormControl 对象并将它们设置为“原始”吗?此后用户的任何更改都将触发表单或控件的valueChanges

    在将所有FormControl 项目设置为touched(触发验证设置)的递归方法下方,您可以对control.markAsUntouchedcontrol.markAsPristine 使用相同的方法?

    export function markFormGroupTouched(formGroup: FormGroup): void {  
      const fa = new FormArray([]).constructor.name;
      Object.values(formGroup.controls).forEach((control: any, i) => {
        if (control.constructor.name === fa) {
          control.controls.forEach((ctrl: any) => markFormGroupTouched(ctrl));
        }    
        else{
          control.markAsTouched();
        }          
      });
    }
    

    函数对于 FormArray 是递归的,因此它将遍历整个 form.controls 树。

    注意:const fa = new FormArray([]).constructor.name; 是为了避免 缩小代码的问题。因为typeof FormArrayFormGroup 的形式返回,您必须在控件上进行比较 构造函数,但 FormArray 的工厂被重命名为 缩小,因此您不能硬编码..=="FormArray",因为在缩小时它不会是构造函数名称。这种方法考虑到了这种意外情况。

    【讨论】:

      猜你喜欢
      • 2020-06-06
      • 2015-08-26
      • 2011-08-31
      • 2017-11-26
      • 2022-10-08
      • 1970-01-01
      • 2011-11-15
      • 2022-01-23
      • 1970-01-01
      相关资源
      最近更新 更多