ngRepeatの「トラックバイ」式を理解する


101

angularjsでのng-repeatの表現によるトラックがどのように機能するかを理解するのが困難です。ドキュメントは非常に少ないです:http : //docs.angularjs.org/api/ng/directive/ngRepeat

これらの2つのコードスニペットの違いは、データバインディングと他の関連する側面の点でどのように説明できますか?

と: 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はモニカを2018

あなたが正しい!TJの答えを受け入れました。
Jonathan Grupp、2018

回答:


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
ご回答有難うございます!しかし、確かに重複した識別子が唯一のユースケースではありません。また、「内部」で何が起こっているのか知りたいのですが。
Jonathan Grupp 2014年

2
まあ、簡単です:ちょうど見ていたコードを、それはすべてのオープンソースだ;)
nilsK

4
この質問は古いですが、私はこれがはるかに優れたbennadel.com/blog/…ここの説明の短いバージョンを理解するのに役立つと思い ます docs.angularjs.org/error/ngRepeat/dupes
Annapoorni D

3
もう1つ考慮すべき点は、キーによる追跡を使用できる場合は、パフォーマンスが向上することです(blog.500tech.com/is-reactjs-fast)。この機能により、一意の識別子を使用してJavaScriptオブジェクトをngRepeat DOM(ドキュメントオブジェクトモデル)ノードに関連付けることができます。この関連付けが適切に行われると、AngularJSは$ destroyを実行せず、DOMノードを不必要に再作成しません。これにより、パフォーマンスとユーザーエクスペリエンスが大幅に向上します(bennadel.com/blog/…)。
Braulio 2015年

700個の奇妙なアイテムのリストがあります。レンダリング時間は4秒から100ミリ秒になりました。Track Byは、残りから供給されたデータに基づくすべてのngRepeatに使用する必要があります。
Patrick

60

短い要約:

track by ng-repeatによって作成されたDOM生成(および主に再生成)とデータをリンクするために使用されます。

追加するtrack byとき、基本的にangularに与えられたコレクションのデータオブジェクトごとに単一のDOM要素を生成するように伝えます

これは、ページングやフィルタリング、またはオブジェクトがng-repeatリストに追加またはリストから削除される場合に役立ちます。

通常、track byangularを使用しない場合は、expandoプロパティを$$hashKeyJavaScriptオブジェクトに挿入することで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/

(追跡は、角度> 1.2で利用できます)


8

オブジェクト全体ではなく識別子(たとえば、$ index)でオブジェクトトラックを操作していて、後でデータを再ロードする場合、ngRepeat 、コレクション内のJavaScriptオブジェクトが持ってても、すでにレンダリングしたアイテムのDOM要素再構築しません新しいものに置き換えられました。


これを証明するリファレンスはありますか?
azerafati 2017

再レンダリングを強制する方法はありますか?または他の回避策はありますか?私はこれについてどこにも言及していませんが、これが私にとって混乱を引き起こしているものだと私は信じており、すでに多くの時間を無駄にしています。
NeverGiveUp161 2018

1
オブジェクトの変更時にトラックバイを使用しないか、一意の識別子を変更します。$ indexを変更することはできません。代わりに$ indexを使用しないことをお勧めします。代わりにオブジェクトに固有の識別子(idなど)を使用します
ram1993
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.