Что такое "track by" в AngularJS и как это работает?
Я действительно не понимаю, как track by
работает и что она делает.
Моя главная цель-использовать его с ng-repeat
чтобы добавить некоторую точность.
3 ответов
используя track by
для отслеживания строк и повторяющихся значений
нормально ng-repeat
отслеживает каждый элемент по самому элементу. Для данного массива objs = [ 'one', 'one', 2, 'five', 'string', 'foo']
, ng-repeat
пытается отслеживать изменения по каждому obj
на ng-repeat="obj in objs"
. Проблема в том, что у нас есть дубликаты значений, и angular выдаст ошибку. Один из способов решить эту проблему-угловое отслеживание объектов другими средствами. Для строк track by $index
является хорошим решением, поскольку у вас действительно нет других средств для отслеживания строка.
track by
& запуск дайджеста и ввод фокусов
вы намекаете на то, что вы несколько новичок в angular. Цикл дайджеста происходит, когда angular выполняет исчерпывающую проверку каждого наблюдаемого свойства, чтобы отразить любое изменение в представлении correspodant; часто во время дайджеста происходит, что ваш код изменяет другие наблюдаемые свойства, поэтому процедуру необходимо выполнить снова, пока angular не обнаружит больше изменений.
например: вы нажмите кнопку, чтобы обновить модель через ng-click
, затем вы делаете что-то (я имею в виду, то, что вы написали в обратном вызове, чтобы выполнить, когда пользователь делает щелчок), затем угловой триггер дайджест цикла для обновления представления. Я не слишком четко объясняю это, поэтому вы должны исследовать дальше, если это не прояснило вещи.
Итак, вернемся к track by
. Приведем пример:
- вызов службы для возврата массива объектов
- обновить объект в массиве и сохранить объект
- после сохранения службы, в зависимости от того, что возвращает API, вы можете:
- заменить весь объект или
- обновить значение существующего объекта
- отразить изменения в
ng-repeat
UI
как вы отслеживаете этот объект, определит, как пользовательский интерфейс отражает изменение.
один из самых раздражающих UXs, которые я испытал, это. Скажем, у вас есть стол объекты, каждая ячейка имеет вход, где вы хотите в строке редактировать свойства этих объектов. Я хочу изменить значение, то on-blur
, сохраните этот объект при перемещении в следующую ячейку для редактирования во время ожидания ответа. Итак,это автосохранение. В зависимости от того, как вы настраиваете свой track by
оператор, вы можете потерять текущий фокус (например, поле, которое вы в настоящее время редактируете), когда ответ будет записан обратно в массив объектов.
при добавлении track by
вы в основном говорите angular генерировать один элемент DOM для каждого объекта данных в данной коллекции.
вы можете track by $index
если ваш источник данных имеет повторяющиеся идентификаторы.
Если вам нужно повторить повторяющиеся элементы,вы можете заменить поведение отслеживания по умолчанию своим собственным, используя трек по выражению.
пример:
[{id:1,name:'one'}, {id:1,name:'one too'}, {id:2,name:'two'}]
попробуйте использовать повторяющиеся значения в ng-repeat
, вы получите сообщение об ошибке например:
ошибка: ngRepeat: обманывает дубликат ключа в повторителе
чтобы избежать такого рода проблем, вы должны использовать track by $index
. Например:
<ul>
<li ng-repeat="item in [1, 2, 3, 3] track by $index">
{{ item }}
</li>
</ul>
вот как вы получите $index
во вложенных ng-repeat
:
<div ng-repeat="row in matrix">
<div ng-repeat="column in row">
<span>outer: {{$parent.$index}} inner: {{$index}}</span>
</div>
</div>
вот некоторые ресурсы, которые могут помочь вам:
вы должны использовать track by
только если вам нужно пойти против поведения по умолчанию ng-repeat
который должен удалить повторяющиеся элементы.
Вы можете отслеживать элементы с помощью свойства scope $index
или указание пользовательской функции.
например:
<div ng-repeat="x in [42, 42, 43, 43] track by $index">
{{x}}
</div>
отобразить все значения массива (42 отображается дважды).
для справки:https://docs.angularjs.org/api/ng/directive/ngRepeat