ngFor 中调用的方法多次触发

method called in ngFor gets trigger for multiple times

即使在 ngFor 中有 2 个项目,我也在 ngFor 中调用一个方法来获取输入标签的触发器 8 次。它应该只被调用两次。它被多次调用的原因可能是什么。

<form [formGroup]="parentForm">
   <div formGroupName="child">
    <ng-container *ngFor="let item of parentForm.get('child').controls | keyvalue; let i = index">
      <div class="form-group">
      <label>{{getLabel(item.key)}} {{i}} </label>
      <input type="text" [formControlName]="item.key">
      </div>
    </ng-container>
   </div>
  </form>   
  getLabel(item) {
     console.log('trigger item') // its get printed in console for 8 times
  if(item == 'data')  { 
    return 'Your Data' 
  } 
  return 'Your Name'
  }

游乐场:https://stackblitz.com/edit/angular-ivy-hnaegv?file=src%2Fapp%2Fapp.component.html

正如@ukn 在评论中提到的,您不应在模板上使用函数调用。

getLabel 函数在每次 Angular 变化检测运行时执行。

您可以避免多次函数调用,使用管道。让 Angular 知道如果管道的输入没有改变,可以安全地跳过管道的执行

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'getLabel'
})
export class GetLabelPipe implements PipeTransform {

  transform(value: any, args?: any): any {
         console.log('trigger item')
  if(value == 'data')  { 
    return 'Your Data' 
  } 
  return 'Your Name'
  }

}

Example

最好先使用 javascript 来组织您的数据。那么你的 html 应该只在 ngFor 循环中显示数据:

var displayItems = [];
parentForm.get('child').controls.forEach(item => {
    item.label = getLabel(item.key);
    displayItems.push(item);
});
this.displayItems = displayItems;

html;

<div *ngFor="let item of displayItems">
  <label>{{item.label}} {{i}} </label>
</div>