Понимание выражения ngRepeat 'track by'

У меня возникают трудности с пониманием того, как работает отслеживание выражения ng-repeat в angularjs. Документация очень скудная: 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>

Ответ 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>

Ответ 2

краткое резюме:

track by используется для связывания ваших данных с генерацией DOM (и главным образом повторного генерации), выполненной с помощью ng-repeat.

когда вы добавляете track by, вы в основном указываете angular на создание одного элемента DOM для каждого объекта данных в данной коллекции

это может быть полезно при пейджинге и фильтрации, или в любом случае, когда объекты добавляются или удаляются из списка ng-repeat.

обычно без track by angular свяжет объекты DOM с коллекцией, введя свойство expando - $$hashKey - в ваши объекты JavaScript и будет регенерировать его (и повторно ассоциировать объект 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/

(трек доступен в angular > 1.2)

Ответ 3

Если вы работаете с объектами отслеживаете по идентификатору (например, $index) вместо всего объекта, и позже вы загружаете свои данные, ngRepeat не будет перестраивать элементы DOM для элементов, у которых уже представлен, даже если объекты JavaScript в коллекции были заменены новыми.