我对Angular中这个循环的行为有点困惑: 对5个字段的数组进行简单的*ngFor循环

<div *ngFor="let field of this.fields" >
  <div class="block">{{ field.title }} : {{getValue(field)}}</div>
</div>

功能getValue

getValue(field) {
    console.log("getValue: "+ this._counter++, field.title);
    return field.name;
}

鉴于数组只有5个字段,我预计函数getValue只执行5次(或数组中的项目数),但正如您从this fiddle中看到的那样,它在第一次运行时执行了20次,并且状态的任何变化都会使它多运行10次.(从控制台阅读)

事实上,当页面加载时,只有1个项的数组将运行4次,并且任何状态变化都会导致它运行两次.

这在具有数百数组和运行以获取数据的复杂函数的适当应用程序中变得更加明显.

这似乎对于Angular的所有版本都是一样的(至少我从v4-v16测试过的版本)

所以我很好奇.首先,为什么它执行这么多次,其次,鉴于有一个复杂的函数来返回数据,是否有更有效的方法来循环数组?

推荐答案

每次将函数写入.html中的插值时,Angular每次都应该执行以了解"一些是否发生了变化".

当您使用变量Angular时,将变量的值与其旧值进行比较,但如果您使用函数Angular应该执行该函数以获取实际值.

您可以尽量减少使用ChangeDetectionStrategy.OnPush(这会产生更多影响,并确保在使用前了解与否).

如果你写一个简单的,就会发生同样的情况

{{getValue()}}

getValue()
{
   return "hello word"
}

总的来说,这就是我们在有循环时应该避免使用.html中的函数的原因.如果是数组,您可以写一些类似的内容

this.fieldsExtends=this.fields.map(x=>({...x,value:this.getValue(x)}))

并且您可以在现场进行扩展

<!--NOTE: in .html remove the "this", the only variables that you can show
    are the public variables of your component-->

<div *ngFor="let field of fieldsExtends" >
  <div class="block">{{ field.title }} : field.value}</div>
</div>

Angular相关问答推荐

他们如何删除Clarity中的Angular组件包装器元素

cat Owl carousel 位置下一个和上一个图片

布局之间的Angular 变化检测需要重新加载

接收错误NullInjectorError:R3InjectorError(_AppModule)[config—config]....>过度安装Angular—Markdown—Editor

间歇性不正确的SSR重定向(server. ts级别的请求和响应不匹配)

无法绑定到appendTo,因为它不是p-confirmPopup的已知属性

Ngrx Select 器返回部分对象

VS代码中带Angular 17的缩进新控制流

FromEvent不工作,本机事件绑定

我的验证器收到一个始终为空的可观察值

如何正确导出/导入枚举和接口文件以便 Jest 成功完成测试?

Angular 不使用NgRx的简单CRUD应用程序

相同的 Angular 代码在生产环境中停止工作

Angular ngSubmit 不起作用(内部按钮和导入模块)

Nz 树 Select .如何在子 node 中显示父 node 名称?

错误:在工作区外运行 Angular CLI 时,此命令不可用

Angular 6在输入键上添加输入

在Angular2 Dart中设置路由和RouterLink的正确方法是什么

Angular 2 输出到router-outlet

Angular CLI 为已经存在的组件创建 .spec 文件