【问题标题】:Understanding the ngRepeat 'track by' expression了解 ngRepeat 'track by' 表达式
【发布时间】:2014-05-10 18:40:42
【问题描述】:

我很难理解 angularjs 中 ng-repeat 的 track by 表达式的工作原理。文档非常稀缺:http://docs.angularjs.org/api/ng/directive/ngRepeat

你能解释一下这两个sn-ps代码在数据绑定和其他相关方面的区别吗?

与: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>

【问题讨论】:

    标签: javascript angularjs angularjs-ng-repeat


    【解决方案1】:

    如果您的数据源有重复的标识符,您可以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>
    

    【讨论】:

    • 感谢您的回答!但可以肯定的是,重复的标识符并不是唯一的用例。我也想知道“幕后”发生了什么。
    • 嗯,这很简单:看看code,它都是开源的;)
    • 这个问题很老,但我仍然认为这可能有助于更好地理解bennadel.com/blog/…这里的解释的简短版本docs.angularjs.org/error/ngRepeat/dupes
    • 还有一点需要考虑的是,如果你可以使用track by key,你会得到更好的性能(blog.500tech.com/is-reactjs-fast)。此功能允许您使用唯一标识符将 JavaScript 对象与 ngRepeat DOM(文档对象模型)节点相关联。有了这个关联,AngularJS 就不会不必要地 $destroy 和重新创建 DOM 节点。这可以带来巨大的性能和用户体验优势 (bennadel.com/blog/…)。
    • 我有一个包含 700 个奇怪项目的列表。渲染时间从 4 秒变为 100 毫秒。 Track by 应该用于所有 ngRepeat 的基于来自 rest 的数据。
    【解决方案2】:

    简短的总结:

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

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

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

    通常,如果没有track by,Angular 将通过将 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 可以在 angular > 1.2 中使用)

    【讨论】:

      【解决方案3】:

      如果您使用对象按标识符跟踪(例如 $index)而不是整个对象,并且稍后重新加载数据,则 ngRepeat 不会重建 DOM 元素 对于它已已呈现的项目,即使集合中的 JavaScript 对象已被替换为新对象。

      【讨论】:

      • 任何可以证明这一点的参考资料?
      • 有没有办法强制重新渲染?或任何其他解决方法?我在任何地方都没有发现这个,但我相信这给我造成了混乱,我已经浪费了很多时间。
      • 要么不要使用track by,要么不要在更改对象时更改唯一标识符。请注意,您不能更改 $index,建议不要使用 $index,而是使用对象唯一的标识符(例如 id)
      猜你喜欢
      • 2014-06-17
      • 2015-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      相关资源
      最近更新 更多