繁体   English   中英

Angular-使用异步管道的ngFor和trackBy

[英]Angular - ngFor and trackBy with async pipe

我想使用trackBy来提高性能。 该列表的数据在更改时应该是不变的,并通过异步管道提供给模板。 虽然我一直在使用trackBy功能,但是每次发出新值时都会重新渲染整个列表。 即使数组内的对象使用相同的id保持不变,也会发生这种情况。

零件

export class AppComponent implements OnInit {
  data: Observable<any>;

  trackBy(index, item) {
    return item.id;
  }

  ngOnInit() {
    const data = interval(100).pipe(mapTo([
      { id: 1 }, { id: 2 }
    ]))

    this.data = data.pipe(map(events => events.map(event => ({ ...event }))));
  }
}

模板

<div *ngFor="let d of data | async; trackBy: trackBy">{{d}}</div>

此外,这里还有一个StackBlitz 每次将新值发送到ngFor渲染div标签。

据我了解trackBy它应该检测对象是相同的(通过id属性),尽管引用已更改。 还是我明显错过了什么?

没错,当对象不变时,可以使用trackBy来避免重新渲染组件。 在字符串或数字上执行ngFor时,对于Angular来说是显而易见的,但对复杂对象则不然。

从这个Observable开始,我做了一个小例子来解释不同的情况:

this.animals = interval(1000)
    .pipe(take(30),
    map(v => ({ id: v} as Animal)),
    scan((acc, curr) => [...acc, curr], []));

此Observable的结果:

 []
 [{id: 0}]
 [{id: 0}, {id: 1}]
 ...

我创建了一个组件,该组件在每次渲染时均显示输入并具有随机颜色,以使渲染更加明显。

在使用此trackBy功能时,列表每次更改时都会渲染所有组件:

trackBy(index, item) {
    return Math.random();
}

使用trackBy函数时,每个组件仅呈现一次:

trackBy(index, item) {
    return item.id;
}

在这里您可以找到正在运行的示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM