了解ngRepeat的“跟踪依据”表达


101

我很难理解angularjs中ng-repeat表达式的轨迹是如何工作的。该文档非常稀缺:http : //docs.angularjs.org/api/ng/directive/ngRepeat

您能解释一下这两个代码片段在数据绑定和其他相关方面的区别吗?

与: track by $index

<!--names is an array-->
<div ng-repeat="(key, value) in names track by $index">
  <input ng-model="value[key]">                         
</div>

没有(相同的输出)

<!--names is an array-->
<div ng-repeat="(key, value) in names">
   <input ng-model="value[key]">                         
</div>

一个很好的问题,很好的答案!遗憾的是,OP没有接受答案-还是您认为问题回答正确?
Mawg说恢复Monica

你是对的!我刚刚接受了TJ的回答。
乔纳森·格鲁普

Answers:


96

你可以track by $index,如果您的数据源中有重复的识别码

例如: $scope.dataSource: [{id:1,name:'one'}, {id:1,name:'one too'}, {id:2,name:'two'}]

使用“ id”作为标识符时,您不能迭代此集合(重复的id:1)。

不会工作:

<element ng-repeat="item.id as item.name for item in dataSource">
  // something with item ...
</element>

但是可以,如果使用track by $index

<element ng-repeat="item in dataSource track by $index">
  // something with item ...
</element>

1
感谢您的回答!但是可以肯定的是,重复的标识符并不是唯一的用例。我也想知道“幕后”发生了什么。
乔纳森·格鲁普

2
好吧,这很容易:只需看一下代码,它们都是开源的;)
nilsK 2014年

4
这个问题很老,但我仍然认为这可能有助于更好地理解 bennadel.com/blog/…此处的简短解释 docs.angularjs.org/error/ngRepeat/dupes
Annapoorni D

3
要考虑的另一件事是,如果您可以按键使用跟踪,则将获得更好的性能(blog.500tech.com/is-reactjs-fast)。此功能使您可以使用唯一标识符将JavaScript对象与ngRepeat DOM(文档对象模型)节点关联。有了这种关联,AngularJS不会$ destroy并不必要地重新创建DOM节点。这可以带来巨大的性能和用户体验收益(bennadel.com/blog/…)。
Braulio

我有700个奇数物品清单。渲染时间从4秒变为100ms。跟踪依据应用于所有基于rest的数据的ngRepeat。
帕特里克

60

简短摘要:

track by 用于将数据与ng-repeat生成的DOM生成(主要是重新生成)链接。

当您添加时,track by您基本上会告诉angular为给定集合中的每个数据对象生成一个DOM元素

这在分页和过滤时,或在ng-repeat列表中添加对象或从列表中删除对象的任何情况下都非常有用。

通常,没有track by角度的情况是通过将expando属性-注入$$hashKey到JavaScript对象中来将DOM对象与集合链接起来,并且每次更改都会重新生成它(并重新关联DOM对象)。

完整说明:

http://www.bennadel.com/blog/2556-using-track-by-with-ngrepeat-in-angularjs-1-2.htm

更实用的指南:

http://www.codelord.net/2014/04/15/improving-ng-repeat-performance-with-track-by/

(track by在角度> 1.2中可用)


8

如果您正在使用按标识符(例如$ index)而不是整个对象进行跟踪的对象,并且稍后再加载数据,则ngRepeat 将不会为其已呈现的重建DOM元素,即使该集合中的JavaScript对象具有被新的代替。


任何证明这一点?
azerafati

有没有办法强制重新渲染?或其他解决方法?我在任何地方都没有提到这个问题,但是我相信这就是给我造成混乱的原因,我已经浪费了很多时间。
NeverGiveUp161 '18

1
要么不使用跟踪依据,要么更改对象的唯一标识符。请注意,您不能更改$ index,建议不要使用$ index而是使用对象唯一的标识符(例如id)
ram1993
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.