Розуміння виразу ngRepeat 'track by'


101

У мене виникають труднощі з розумінням того, як працює трек із виразом ng-повтору в 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>

Чудове запитання, з дуже хорошими відповідями! Шкода, що ОП не прийняла відповідь - чи ти не вважаєш, що на питання відповіли правильно?
Мауг каже, що повернемо Моніку

Ти маєш рацію! Я щойно прийняв відповідь TJ.
Джонатан Групп

Відповіді:


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
Дякую за вашу відповідь! Але, безумовно, дублюючі ідентифікатори - не єдиний приклад використання. Також я хотів би знати, що відбувається "під капотом".
Джонатан Групп

2
ну, це просто: просто подивіться на код , це все з відкритим кодом;)
nilsK

4
Це питання старе, але я все ще думаю, що це може допомогти зрозуміти набагато краще bennadel.com/blog/… коротка версія пояснення тут docs.angularjs.org/error/ngRepeat/dupes
Annapoorni D

3
Ще одне, що потрібно врахувати, це те, що якщо ви зможете використовувати трек за ключем, ви отримаєте кращу продуктивність (blog.500tech.com/is-reactjs-fast). Ця функція дозволяє асоціювати об’єкт JavaScript з вузлом ngRepeat DOM (Document Object Model), використовуючи унікальний ідентифікатор. Якщо ця асоціація встановлена, AngularJS не знищить і не створить DOM-вузли без потреби. Це може мати величезну ефективність та користь для користувачів ( bennadel.com/blog/… ).
Брауліо

У мене є список з 700 непарних предметів. Час візуалізації піднявся від 4 секунд до 100 мс. Track by слід використовувати для всіх ngRepeat на основі даних, отриманих від спокою.
Патрік

60

короткий підсумок:

track by використовується для того, щоб зв’язати ваші дані з генерацією DOM (і головним чином повторним поколінням), зробленою ng-повтором.

коли ви додаєте, track byви в основному говорите кутовий для створення одного елемента DOM на кожен об'єкт даних у даній колекції

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

зазвичай без track byкутового зв’язує об’єкти DOM зі колекцією шляхом введення властивості експандо - $$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/

(Доріжка доступна у куті> 1.2)


8

Якщо ви працюєте з відстеженням об'єктів за ідентифікатором (наприклад, $ index) замість цілого об'єкта, і ви перезавантажуєте свої дані пізніше, ngRepeat не відновить елементи DOM для елементів, які він вже видав , навіть якщо об’єкти JavaScript у колекції мають були замінені на нові.


будь-яка посилання, яка це підтверджує?
azerafati

чи існує спосіб примусового повторного відтворення? чи будь-яка інша робота навколо? я не знайшов цього згаданого ніде, але я вважаю, що це те, що створює для мене безлад, і я вже витрачав багато часу.
NeverGiveUp161

1
або не використовуйте трек або не змінюйте унікальний ідентифікатор, що змінюється. Зауважте, що ви не можете змінити $ index, рекомендується не використовувати $ index, а не використовувати ідентифікатор, унікальний для об'єкта (наприклад, id)
ram1993,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.