0

<div>我有一个使用*ngFor指令生成的简单列表,例如

<div *ngFor="let item of items() | async ; let i=index" 
  [ngClass]="getItemClass(i)"
  (click)="itemClick(i)"</div>

如您所见,只要方法返回的 Observableitems()发出,列表就会异步填充。在我的情况下,这样的 Observable 是 a ReplaySubject,如果知道这有什么用的话。然后,我使用 方法定义要应用于每个<div>元素的类getItemClass

我还想使用方法对每个项目的点击事件做出反应itemClick(i: number)

问题

任何时候单击一个div元素,即任何时候itemClick(i: number)运行该方法,似乎整个<div>s 列表都被重建了。我得出这个结论,观察到任何时候div单击一个元素,该items()方法也会运行。

问题

<div>单击其中一个元素时是否可以避免重建列表?我已经设置changeDetectionOnPush但它似乎并没有解决我的问题。

4

1 回答 1

5

是的,即使使用 onPush 也会触发更改检测。这将导致 index() 方法的评估。这在文档中有点丢失。任何将冒泡到 zone.js 代码的事件都会触发对从根到该组件的每个组件的更改检测。设置 onPush 不会阻止这种情况。为了避免在循环中重新创建组件,您需要添加 trackBy。

在您的 html 模板中:

<li *ngFor="let hr of heroes;trackBy: trackByFn">{{hr.name}}</li>

然后在组件中你必须定义函数:

trackByFn(index, item) {    
   return item.id  
}

项目是从循环中传递的。如果该项目的 id 不会更改,则不会重新创建该项目。

此外,我会摆脱 index() 方法并将其替换为变量。正如我提到的,每次更改检测运行时都会对其进行评估。我写了一篇关于一些性能技巧的文章,你可以采取这些技巧来加速你的应用程序。

https://medium.com/12-developer-labors/some-things-i-wish-i-knew-before-i-start-to-work-with-angular-part-2-performance-47cd834dc409

于 2018-12-29T11:16:50.200 回答