По-видимому, я еще не понял механика за ng-repeat
, $$hashKeys
и track by
.
В настоящее время я использую AngularJS 1.6 в своем проекте.
Проблема:
У меня есть массив сложных объектов, которые я хочу использовать для рендеринга списка в моем представлении. Но для получения требуемого результата мне нужно сначала изменить (или изменить/изменить/изменить) эти объекты:
const sourceArray = [{id: 1, name: 'Dave'}, {id:2, name: Steve}]
const persons = sourceArray.map((e) => ({enhancedName: e.name + e.id}))
//Thus the content of persons is:
//[{enhancedName: 'Dave_1'}, {enhancedName: 'Steve_2'}]
Связывание этого с представлением должно работать следующим образом:
<div ng-repeat="person in ctrl.getPersons()">
{{person.enhancedName}}
</div>
Однако это явно затекает в $digest()
-loop, потому что .map
возвращает новые объекты-экземпляры каждый раз, когда он вызывается. Поскольку я привязываю это к ng-repeat через функцию, он переоценивается в каждом $digest
, модель не стабилизируется, а Angular сохраняет повторные t $digest
-циклы, потому что эти объекты помечены как $dirty
.
Почему я запутался
Теперь это не новая проблема, и для этого есть несколько решений:
В a Angular -Issue с 2012 года Игорь Минар сам предложил установить $$ hashKey-Property вручную, чтобы сообщить Angular, что сгенерированные объекты одинаковы. Это является его рабочей скрипкой, но так как даже этот очень простой пример по-прежнему сталкивался с $digest
-loop, когда я использовал его в своем проекте, я попробовал модернизировать Angular -Version в скрипке. По какой-то причине он сработает.
Хорошо... с Angular 1.3 мы имеем track by
, который должен по существу решить эту точную проблему. Однако оба
<div ng-repeat="person in ctrl.getPersons() track by $index">
и
<div ng-repeat="person in ctrl.getPersons() track by person.enhancedName">
сбой -loop. У меня создалось впечатление, что оператор track by
должен позволить Angular полагать, что он работает с одними и теми же объектами, но, видимо, это не так, поскольку он просто проверяет их на наличие изменений. Честно говоря, я понятия не имею, как я могу правильно отладить причину этого.
Вопрос:
Можно ли использовать фильтрованный/модифицированный массив в качестве источника данных для ng-repeat?
Я не хочу хранить модифицированный массив на моем контроллере, потому что мне нужно постоянно обновлять его данные, а затем поддерживать и обновлять его вручную в контроллере вместо того, чтобы полагаться на привязку данных.