* ng对于使用函数,返回一个循环

Wen*_*ick 1 templatebinding typescript ngfor angular

当我在带有返回我的数据的函数的angular中使用* ngFor时,该函数被多次调用,有时甚至会导致循环:

app.component.ts

export class AppComponent {

 getArray(): string[] {

   //here i know when this function is called
   console.log('getArray called')

   return ['number one', 'number two']
 }

}
Run Code Online (Sandbox Code Playgroud)

app.component.html

<h1 *ngFor="let item of getArray()">
 {{ item }}
</h1>
Run Code Online (Sandbox Code Playgroud)

我的控制台:

在此处输入图片说明

然后我得到了多次调用函数getArray(),我不知道为什么。

yur*_*zui 5

更新资料

您会看到它称为乘以时间,因为Angular在每个更改检测周期都会评估您在模板中使用的所有表达式。更改检测周期从ApplicationRef.tick方法开始。

应用程序启动时,它将立即调用该tick方法,然后由ngZone.onMicrotaskEmpty订阅进行管理。

另外,每个tick方法针对开发人员模式执行附加的check checkNoChanges

所以你得到

App starts
   loadComponent
      tick
        checkChanges
              evaluate getArray()
        checkNoChanges
              evaluate getArray()
  ngZone.onMicrotaskEmpty
      subscribe(all promised have been executed)
         tick
           checkChanges
              evaluate getArray()
           checkNoChanges
              evaluate getArray()

      ...some time later
      subscribe(you click somewhere)
         tick
           checkChanges
              evaluate getArray()
           checkNoChanges
              evaluate getArray()
      subscribe(you make a http request)
         tick
           checkChanges
              evaluate getArray()
           checkNoChanges
              evaluate getArray()
Run Code Online (Sandbox Code Playgroud)

先前的答案

您应避免在Angular模板中使用执行复杂计算,执行副作用或在每次更改检测运行时返回新值的表达式。

特别是在您的代码中

<h1 *ngFor="let item of getArray()">
Run Code Online (Sandbox Code Playgroud)

您在每次模板检查时都会返回一个新数组。ngForOf指令检测到您更改了数组并尝试重新呈现(如果您的项目将是一个对象)。

最好在代码中一次定义该数组。

arr = ['number one', 'number two']

<h1 *ngFor="let item of arr">
Run Code Online (Sandbox Code Playgroud)

ngForOf指令的另一种有效方法是使用trackBy,但最好在项目中使用一些唯一的键。

也可以看看