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'
}
}
最好先使用 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>
即使在 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'
}
}
最好先使用 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>