Что такое "отслеживание" в 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 не обнаружит больше изменений.

Например: вы нажимаете кнопку, чтобы обновить модель с помощью ng-clickЗатем вы делаете что-то (я имею в виду то, что вы написали в обратном вызове, чтобы выполнить, когда пользователь делает щелчок), затем угловой цикл запуска дайджеста, чтобы обновить представление. Я не слишком ясно объясняю это, поэтому вам следует продолжить расследование, если это не прояснило ситуацию.

Итак, вернемся к track by, Давайте использовать пример:

  1. вызвать сервис для возврата массива объектов
  2. обновить объект в массиве и сохранить объект
  3. после сохранения сервиса, в зависимости от того, что возвращает API, вы можете:
    1. заменить весь объект ИЛИ
    2. обновить значение существующего объекта
  4. отражать изменения в ng-repeat UI

То, как вы будете отслеживать этот объект, будет определять, как пользовательский интерфейс отражает изменения.

Это один из самых раздражающих UX, которые я когда-либо испытывал. Скажем, у вас есть таблица объектов, в каждой ячейке есть вход, где вы хотите оперативно редактировать свойства этих объектов. Я хочу изменить значение, затем 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 который должен удалить дубликаты.
Вы можете отслеживать элементы, используя свойство области $index или указание пользовательской функции.

Например:

<div ng-repeat="x in [42, 42, 43, 43] track by $index">
  {{x}}
</div>

Показать все значения массива (42 отображается дважды).

Для справки: https://docs.angularjs.org/api/ng/directive/ngRepeat

Допустим, у нас есть следующий список:

<ul>
   <li ng-repeat="item in items">
       {{ item }}
   </li>
</ul>

где элемент имеет следующую структуру:

{ 'id'=>id, 'name'=>name, 'description'=>description }

В этом списке нет никаких проблем, пока мы не захотим его обновить. Для нашего удобства мы заменяем список элементов другим обновленным списком элементов, как таковых:

items = newItems;

Однако в этом новом списке изменилось несколько пунктов. Большинство предметов остаются прежними. К сожалению, Angular не знает, как идентифицировать наши элементы и сопоставить их с соответствующими<li>elements, поэтому он просто удаляет все элементы и создает их снова. В некоторых случаях это чрезвычайно затратно по производительности, и вот гдеtrack by входит в обиход.

Добавив track by предложение к элементу

<li ng-repeat="item in items track by item.id">

мы информируем Angular, что уникальный идентификатор наших товаров item.id. Теперь Angular знает, что нужно воссоздавать не все элементы, а только элементы с новыми идентификаторами, и обновляет только остальные. Улучшение производительности в большинстве случаев является значительным. Кроме того, лично мне нравится, что я могу легче отслеживать свои элементы с помощью инструментов разработчика в моем браузере, потому что они не исчезают каждый раз, когда я их обновляю.

Другие вопросы по тегам