Typescript 嵌套表单组触发器多次进行更改检测

Typescript 嵌套表单组触发器多次进行更改检测,typescript,angular9,reactive-forms,formarray,formgroups,Typescript,Angular9,Reactive Forms,Formarray,Formgroups,作为参考,我使用被动表单复制了动态嵌套表单组创建 但在向表单数组中添加新表单组时,它会多次触发更改检测 我的代码 component.html <button mat-flat-button color="primary" (click)="addMaterial()">Add</button> <form [formGroup]="positionFormGroup" novalidate>

作为参考,我使用被动表单复制了动态嵌套表单组创建

但在向表单数组中添加新表单组时,它会多次触发更改检测

我的代码

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>
添加
{{option.description}}
组件技术

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);
     
  }
}

导出类AppComponent{
positionFormGroup:FormGroup;
物料控制:FormControl=新的FormControl(“”);
材料过滤:可见;
选项=[
{description:'item1'},
{description:'item2'},
{description:'item3'},
{说明:'item4'}
]
构造函数(专用formBuilder:formBuilder){
}
ngOnInit():void{
this.materialFilteredOptions=this.materialControl.valueChanges
.烟斗(
startWith(“”),
映射(值=>this.options)
);
this.positionFormGroup=this.formBuilder.group({
职位信息:新表格([])
});
这个.addMaterial();
}
ngDoCheck(){
console.log('triggered');
}
添加材料(){
(this.positionFormGroup.get('positionInfos')作为FormArray)。push(this.formBuilder.group({
rowID:'0',
位置:“0”,
idMaterial:'item1',
数量:1,
isDeleted:错,
是的
}));
}
确认{
console.log(this.positionFormGroup.get('positionInfos').value)
}
获取控件(){
console.log((this.positionFormGroup.get('positionInfos')作为FormArray));
返回(this.positionFormGroup.get('positionInfos')作为FormArray);
}
}
也共享了控制台。当我将新表单组添加到表单数组中时,它正在发生。 我不明白为什么它会多次触发更改检测


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

我应该将ChangeDetectionStrategy更改为onPush,这样组件将只呈现一次

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

在做了一些研究之后,我得到了一个答案。每当发生更改检测时,模板都会重新评估方法

直接使用类属性来获取嵌套的表单组控件,而不是控件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">