バインディングはどんなチェックしていない、とだけ異なる場合ダイジェスト・サイクルごとに、更新されます。 DOM要素を再構築する場合、Angularは一意の識別子を使用して、ng-repeat
の各アイテムに既に一致するDOM要素があるかどうか、または新しい要素をレンダリングする必要があるかどうかを判断します。
デフォルトでは、Angularは各オブジェクトの$id
(または$$hashKey
)を使用して、これらの一意の識別子を作成し、管理します。
track by
がAngularに、フードの下で管理するのではなく、あなたの選択した一意の識別子を使用するように指示する方法として追加されました。
これは、データを更新して$id
または$$hashKey
を削除または変更し、データがまったく変更されなかった場合でも各DOM要素の不要な再構築をトリガーする場合に便利です。
は、この例を考えてみましょう:あなたはどのfetch()
方法を持っている、あなたのデータを更新するサービスDataService
を使用
<li ng-repeat="item in data">{{item.value}}</li>
:
あなたは、データレコードを表示するngRepeatを持っていますSQLデータベースからデータを取り出し、レコードを返します。あなたの$scope
内のデータを更新
は、そのサービスを呼び出し、再割り当ての結果に自分のデータ変数が含まれます。
$scope.data = DataService.fetch();
つまり、一つだけのアイテムが異なっていた場合でも、 $id
または$$hashKey
のプロパティはすべて消えていますが、Angularではすべての項目が新しいものとみなします。すべてのDOM要素をゼロから再構築します。
ただし、データはSQLデータベースのものなので、一意の識別子(主キー)、つまりid
の列が既にあります。あなたがあることをごngRepeatを変更することができます:あなたがデータを再割り当てするたびに失われ、代わりに$$hashKey
を探しての、
今 <li ng-repeat="item in data track by item.id">{{item.value}}</li>
、角度は、あなたが(item.id
)にそれを告げたプロパティを使用します。そのプロパティーはが変数を再割り当てしても保持されるため、Angularは新しいitem
のDOMエレメントのみを再ビルドするので、リストは再び最適化されます。
おかげで、その基礎となるデータ構造の一つの要素は、(DOMの再構築)に必要なビューの更新を行う変更した場合、これは「でトラック」を使用して、私はパフォーマンスを大幅に損なうことなく、深くネストされたNG-リピートディレクティブのビューを持つことができることを意味。まだ注意が必要なことはありますか? – snflurry
はい、あなたは正しいです。あなたはまだDOMが最適化されている場合でも、データ収集は、(N + 1つのクエリ、など)ではないかもしれないので、データサービスによって整列化されますどのような最適化しようとする必要がありますけど。癖のためとして、私は考えることができる唯一の一つは、それが常にフィルタやORDERBYとうまく再生されないということです。彼らは( 'by'追跡_before_それらを置く)が、あなたは$ ORDERBYを使用して、コントローラ上でそれらを扱う場合、それははるかに安全でクリーンされて終わる作業することができます。 – rmhunter