何时不在AngularJS ng-repeat中使用'追踪$ index'?

时间:2017-08-16 18:27:53

标签: angularjs angularjs-ng-repeat

我最近收到了控制台错误`

  

错误:不允许在转发器中使用[ngRepeat:dupes]重复项。使用'track by'表达式指定唯一键...

     

— AngularJS Error Reference - ngRepeat:dupes

然后我使用了'track by $index',问题就解决了......

但这让我思考......你有没有理由不想在ng-repeat中使用track by $index

我已经阅读了this one以及other articles这样的问题,但似乎几乎所有文章都只讨论了使用'track by'的优点。

有人可以列出缺点并举例说明何时不想使用track by $index

2 个答案:

答案 0 :(得分:13)

它有一个 'track by'

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

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

请看一下 example

尝试更改名称,没有任何反应。 按索引删除跟踪,它有效。 按item.name添加曲目,它仍然有效。

答案 1 :(得分:9)

避免track by $index

有多种原因
  • 使用one-time bindings
  • 时,请避免使用track by $index
  • 当存在唯一属性标识符时,请避免track by $index
  • track by $index
  • 的其他问题示例

使用one-time bindings

时避免使用track by $index

文档明确指出在使用一次性绑定时应避免使用track by $index

来自文档:

  
    

当重复的模板包含one-time bindings时,请避免使用track by $index。在这种情况下,nth DOM元素将始终与数组的nth项匹配,因此即使相应的项更改,也不会更新该元素上的绑定,从而导致视图与基础数据失去同步。

  
     

— AngularJS ng-repeat Reference - Tracking and Duplicates

当存在唯一属性标识符

时,请避免track by $index

当有唯一的属性标识符可用时,请避免使用track by $index使用全部唯一的对象时,最好ng-repeat使用自己的跟踪,而不是覆盖track by $index

来自文档:

  
    

如果您正在处理具有唯一标识符属性的对象,则应使用此标识符而不是对象实例进行跟踪。如果您稍后重新加载数据,ngRepeat将不必为已呈现的项重建DOM元素,即使集合中的JavaScript对象已替换为新对象。对于大型集合,这可以显着提高渲染性能。

  
     

— AngularJS ng-repeat Directive API Reference - Tracking

track by $index

的其他问题示例

在对象数组中添加和删除对象时,我也遇到了问题。