Ответ 1
Короткий ответ: вам действительно нужна такая функция, или вы можете использовать свойство? http://jsfiddle.net/awnqm/1/
Длинный ответ
Для простоты я опишу только ваш случай - ngRepet для массива объектов. Кроме того, я опускаю некоторые подробности.
Функция AngularJS использует грязную проверку для обнаружения изменений. Когда приложение запускается, он запускает $digest
для $rootScope
. $digest
выполнит обход глубины для иерархии областей. У всех областей есть список часов. Каждый вахта имеет последнее значение (первоначально initWatchVal
). Для каждой области для всех часов $digest
запускает ее, получает текущее значение (watch.get(scope)
) и сравнивает его с watch.last
. Если текущее значение не равно watch.last
(всегда для первого сравнения) $digest
установите dirty
в true
. Когда все области обработки обрабатываются, если dirty == true
$digest
запускает другой обход глубины из $rootScope
. $digest
заканчивается, когда dirty == false или количество обходов == 10. В последнем случае происходит ошибка "10 $digest()". будет зарегистрирован.
Теперь о ngRepeat
. Для каждого вызова watch.get
он хранит объекты из коллекции (возвращаемое значение getEntities
) с дополнительной информацией в кеше (HashQueueMap
hashKey
). Для каждого вызова watch.get
ngRepeat
попытайтесь получить объект из hashKey
из кеша. Если он не существует в кеше, ngRepeat
хранит его в кеше, создает новую область, помещает на нее объект, создает элемент DOM, и т.д..
Теперь о hashKey
. Обычно hashKey
- это уникальный номер, созданный nextUid()
. Но это может быть функция. hashKey
хранится в объекте после генерации для будущего использования.
Почему ваш пример генерирует ошибку: function getEntities()
всегда возвращает массив с новым объектом. Этот объект не имеет hashKey
и не существует в кеше ngRepeat
. Итак, ngRepeat
на каждом watch.get
создает для него новую область с новыми часами для {{entity.id}}
. Эти часы на первом watch.get
имеют watch.last == initWatchVal
. Итак, watch.get() != watch.last
. Итак, $digest
начинает новый траверс. Таким образом, ngRepeat
создает новую область с новыми часами. Итак... после 10 траверсов вы получаете ошибку.
Как вы можете исправить это
- Не создавайте новые объекты при каждом вызове
getEntities()
. - Если вам нужно создать новые объекты, вы можете добавить для них метод
hashKey
. Для примера см. этот раздел.
Надеюсь, что люди, знакомые с внутренними органами AngularJS, исправят меня, если я ошибаюсь.