Angular NG5002: @for loop must have a "track" expression

kac*_*ase 10 javascript angular

Angular 17 introduced a new control flow syntax moving from

<div *ngFor="let item of items"></div>
Run Code Online (Sandbox Code Playgroud)

to

@for (item of items) {
    <div></div>
}
Run Code Online (Sandbox Code Playgroud)

When directly translating my loops, I get the following error:

 NG5002: @for loop must have a "track" expression
Run Code Online (Sandbox Code Playgroud)

kac*_*ase 12

Background

v17中引入的新控制流结构的一部分,track需要定义表达式。

Track 用于跟踪数组中的项目及其与 DOM 的关联。

来自角度文档:

表达式的值track确定用于将数组项与 DOM 中的视图关联起来的键。清楚地指示项目标识允许 Angular 在集合中添加、删除或移动项目时执行最少的 DOM 操作集。

循环不可变数据trackBy是 Angular 应用程序性能问题的最常见原因之一。由于性能可能较差,因此循环track需要该表达式@for。如果有疑问,使用track $index默认值是一个很好的选择。

来自:https://angular.dev/guide/templates/control-flow#track-for-calculate-difference-of-two-collections

解决方案

使用元素的属性

如果数组中的元素附加了任何类型的属性来允许识别它们,则可以将其用于跟踪。任何类型的 ID 都很好用。

let items = [
    { id: "id1", content: []},
    { id: "id2", content: []},
]
Run Code Online (Sandbox Code Playgroud)
@for (item of items; track item.id) {
    <div></div>
}
Run Code Online (Sandbox Code Playgroud)

使用track $index

这使用当前行的索引将该行与 DOM 中的元素关联起来。如果没有更好的属性可用并且数组本身是不可变的,则可以将其用作默认值。

@for (item of items; track $index) {
    <div></div>
}
Run Code Online (Sandbox Code Playgroud)

$index如果将项目添加到数组中,将重新计算,因此可能会导致一些意外的行为或性能问题,并且如果唯一标识符可用,则不应使用。