何时不在 AngularJS ng-repeat 中使用“track by $index”?

问题描述 投票:0回答:2

我最近收到控制台错误`

错误:[ngRepeat:dupes] 中继器中不允许出现重复项。使用“track by”表达式来指定唯一键...

— AngularJS 错误参考 - ngRepeat:dupes

然后我使用了

'track by $index'
,问题就解决了......

但这让我开始思考...你是否有理由不想在 ng-repeat 中使用

track by $index

我读过诸如这个之类的问题以及其他文章,但似乎几乎所有文章都只讨论使用

'track by'
的优点。

有人可以列出缺点并举例说明您何时不想使用

track by $index
吗?

angularjs angularjs-ng-repeat
2个回答
13
投票

有多种原因需要避免

track by $index

  • 使用
    一次性绑定
    时避免使用 track by $index
  • 当存在唯一的属性标识符时,避免
    track by $index
  • track by $index
  • 的其他问题示例

使用
一次性绑定
时避免使用 track by $index

文档特别指出,使用一次性绑定时应避免使用

track by $index

来自文档:

当重复模板包含

一次性绑定
时,避免使用track by $index。在这种情况下,
nth
DOM 元素将始终与数组的
nth
项匹配,因此即使相应项发生更改,该元素上的绑定也不会更新,本质上导致视图脱离-与底层数据同步。

— AngularJS ng-repeat 参考 - 跟踪和重复


当存在唯一的属性标识符时,避免
track by $index

当需要使用唯一的属性标识符时,请避免使用

track by $index
在处理全部唯一的对象时,最好让 ng-repeat
 使用自己的跟踪
,而不是用
track by $index
 覆盖。

来自文档:

如果您正在使用具有唯一标识符属性的对象,则应通过此标识符而不是对象实例进行跟踪。如果您稍后重新加载数据,

ngRepeat

将不必为已渲染的项目重建 DOM 元素,即使集合中的 JavaScript 对象已被新对象替换。对于大型集合,这可以显着提高渲染性能。

— AngularJS ng-repeat 指令 API 参考 - 跟踪


track by $index
的其他问题示例

我还看到了在对象数组中添加和删除对象时出现的问题。

  • 使用 Angular UI Carousel 按 $index 进行跟踪时出现问题
  • Ng-重复显示一次性绑定的不规则行为
  • Angular:使用新数据更新 $scope 会导致使用 ng-repeat 时保留旧数据
  • AngularJS 和 Select 绑定出现问题,无法加载默认值

13
投票
它有一个

缺点

'track by'

 表达式按数组中的索引进行跟踪。这意味着只要索引保持不变,AngularJS就认为它是同一个对象。

因此,如果您替换数组中的任何对象,AngularJS 认为它没有改变,因为数组中的索引仍然相同。因此,更改检测不会在您期望的时候触发。

看一下

这个例子

尝试更改名称,但没有任何反应。 按索引删除轨道,它可以工作。 按item.name添加曲目,仍然有效。

© www.soinside.com 2019 - 2024. All rights reserved.