【问题标题】:Nested Form Group triggeres change detection multiple times嵌套表单组多次触发更改检测
【发布时间】:2020-11-22 07:35:32
【问题描述】:

使用this 作为参考,我复制了使用反应式表单创建动态嵌套表单组。

但是在将新的表单组添加到表单数组中时,它会多次触发更改检测。

我的代码

component.html

<button mat-flat-button color="primary" (click)="addMaterial()">Add</button>

<form [formGroup]="positionFormGroup" novalidate>
  <table formArrayName="positionInfos">

    <div *ngFor="let data of Controls.controls; let i = index">
      <div [formGroupName]="i">

        <input type="text" formControlName="idMaterial" [matAutocomplete]="materialAuto">
        <mat-autocomplete #materialAuto="matAutocomplete">
          <mat-option *ngFor="let option of materialFilteredOptions | async" [value]="option.description">
            {{option.description}}
          </mat-option>
        </mat-autocomplete>
      </div>
    </div>

  </table>
</form>

组件.ts

export class AppComponent {
  positionFormGroup: FormGroup;
  materialControl: FormControl = new FormControl('');
  materialFilteredOptions: Observable<{ description: string; }[]>;
  options = [
    { description: 'item1' },
    { description: 'item2' },
    { description: 'item3' },
    { description: 'item4' }
  ]
  constructor(private formBuilder: FormBuilder) {
  }

  ngOnInit(): void {
    this.materialFilteredOptions = this.materialControl.valueChanges
      .pipe(
        startWith(''),
        map(value => this.options)
      );
    this.positionFormGroup = this.formBuilder.group({
      positionInfos: new FormArray([])
    });

    this.addMaterial();

  }

  ngDoCheck(){
    console.log('triggered');
  }

  addMaterial() {
    (this.positionFormGroup.get('positionInfos') as FormArray).push(this.formBuilder.group({
      rowID: '0',
      position: '0',
      idMaterial: 'item1',
      quantity: 1,
      isDeleted: false,
      isActive: true
    }));
  }

  confirm(){
    console.log( this.positionFormGroup.get('positionInfos').value)
  }

  get Controls(){
    console.log( (this.positionFormGroup.get('positionInfos') as FormArray));
    return (this.positionFormGroup.get('positionInfos') as FormArray);
     
  }
}

也共享控制台。当我将新表单组添加到表单数组中时,它正在发生。 我不明白为什么它会多次触发更改检测。

如果我遗漏了什么,请告诉我。提前致谢

【问题讨论】:

    标签: typescript angular9 reactive-forms formarray formgroups


    【解决方案1】:

    经过一番研究,我得到了答案。每当发生更改检测时,模板都会重新评估该方法。

    代替Controls getter,直接使用类属性来获取嵌套的表单组控件。

    ts

      this.control = this.getControls().controls;
    
      getControls(){
        console.log( (this.positionFormGroup.get('positionInfos') as FormArray));
        return (this.positionFormGroup.get('positionInfos') as FormArray);
      }
    

    html

        <div *ngFor="let data of control; let i = index">
    
    

    【讨论】:

      【解决方案2】:

      我应该将 ChangeDetectionStrategy 更改为 onPush,这样组件只会被渲染一次

      @Component({
        selector: "hello",
        templateUrl: "./hello.component.html",
        changeDetection: ChangeDetectionStrategy.OnPush,
      })
      

      your working example

      【讨论】:

        猜你喜欢
        • 2019-05-07
        • 2016-04-20
        • 2021-06-10
        • 1970-01-01
        • 2021-09-02
        • 2011-10-04
        • 2023-03-06
        • 2021-11-13
        相关资源
        最近更新 更多