짧은 대답 : 정말로 그러한 기능이 필요합니까 아니면 속성을 사용할 수 있습니까? http://jsfiddle.net/awnqm/1/
긴 대답
단순화를 위해 객체 배열에 대한 ngRepeat의 경우 만 설명합니다. 또한 세부 사항은 생략하겠습니다.
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
by hashKey
) 에 추가 정보와 함께 컬렉션 (값 반환)의 개체를 저장합니다 . 모든 watch.get
호출 ngRepeat
에 대해 hashKey
캐시에서 객체를 가져 오려고 합니다. 캐시에 존재하지 않는 경우 캐시에 ngRepeat
저장하고, 새 범위를 생성하고, 객체를 배치하고, DOM 요소를 생성하는 등의 작업을 수행 합니다.
이제 hashKey
. 일반적으로에서 hashKey
생성 한 고유 번호 nextUid()
입니다. 그러나 그것은 기능 일 수 있습니다 . hashKey
나중에 사용하기 위해 생성 후 객체에 저장됩니다.
예제에서 오류가 발생하는 이유 : 함수는 getEntities()
항상 새 객체로 배열을 반환합니다. 이 개체는 캐시에 hashKey
없으며 존재하지 않습니다 ngRepeat
. 따라서 ngRepeat
각각에 watch.get
대한 새 시계를 사용하여 새 범위를 생성합니다 {{entity.id}}
. 이 시계는 처음 watch.get
에 watch.last == initWatchVal
. 그래서 watch.get() != watch.last
. 그래서 $digest
새로운 횡단을 시작합니다. 그래서 ngRepeat
새로운 시계로 새로운 범위를 만듭니다. 그래서 ... 10 번의 트래버스 후에는 오류가 발생합니다.
고칠 수있는 방법
- 모든
getEntities()
호출 에서 새 개체를 만들지 마십시오 .
- 새 개체를 만들어야하는 경우
hashKey
메서드를 추가 할 수 있습니다 . 예제는 이 주제 를 참조하십시오 .
AngularJS 내부를 아는 사람들이 내가 뭔가 잘못되면 나를 바로 잡기를 바랍니다.