*ng对于使用函数,返回一个循环 [英] *ngFor using a function, returns a loop

查看:26
本文介绍了*ng对于使用函数,返回一个循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<块引用>

app.component.ts

导出类 AppComponent {getArray(): 字符串[] {//这里我知道这个函数什么时候被调用console.log('getArray 被调用')return ['第一名','第二名']}}

<块引用>

app.component.html

{{ 物品 }}

<块引用>

我的控制台:

然后我多次调用 getArray() 函数,但我不知道为什么.

解决方案

更新

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

当应用程序启动时调用 立即使用该刻度方法,然后由 ng 管理.onMicrotaskEmpty 订阅.

此外,每个刻度方法都会执行额外的检查 checkNoChanges 用于开发模式.

所以你得到了

应用程序启动加载组件打钩检查更改评估 getArray()检查无变化评估 getArray()ngZone.onMicrotaskEmpty订阅(所有承诺已执行)打钩检查更改评估 getArray()检查无变化评估 getArray()...一段时间以后订阅(你点击某处)打钩检查更改评估 getArray()检查无变化评估 getArray()订阅(您发出 http 请求)打钩检查更改评估 getArray()检查无变化评估 getArray()

上一个回答

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

特别是在你的代码中

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

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

arr = ['第一名','第二名']<h1 *ngFor="let item of arr">

适用于 ngForOf 指令的另一种方法是使用 trackBy,但最好为此在 item 中有一些唯一的键.

另见

When i use *ngFor in angular with a function returning my data, the function is called multiple times, and sometimes resulting even in a loop:

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']
 }

}

app.component.html

<h1 *ngFor="let item of getArray()">
 {{ item }}
</h1>

My console:

Then i get the function getArray() called multiple times and i dont know why.

解决方案

Update

You see that it's called multiply time because Angular evaluates all expressions you're using in your template on every change detection cycle. The change detection cycle starts with ApplicationRef.tick method.

When application starts it calls that tick method immediately and then it's managed by ngZone.onMicrotaskEmpty subscription.

Additionaly, every tick method executes additional check checkNoChanges for dev mode.

So you're getting

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()

Previous answer

You should avoid using expressions in Angular template that execute complex calcultation or perform side effect or return new value on every change detection run.

Particularly in your code

<h1 *ngFor="let item of getArray()">

you're returning a new array on every template check. And ngForOf directive detects that you changed array and tries to rerender it(if your items would be an objects).

It's better if you define that array once in your code.

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

<h1 *ngFor="let item of arr">

Another way that can work for ngForOf directive is using trackBy but it would better to have some unique key in item for that.

See also

这篇关于*ng对于使用函数,返回一个循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆