Понимание выражения 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 в коллекции были заменены новыми.