오류 : 10 $ digest () 반복에 도달했습니다. 중단 중! 동적 정렬 기준 술어


134

사용자 이름과 점수를 반복하여 표시하는 다음 코드가 있습니다.

<div ng-controller="AngularCtrl" ng-app>
  <div ng-repeat="user in users | orderBy:predicate:reverse | limitTo:10">
    <div ng-init="user.score=user.id+1">
        {{user.name}} and {{user.score}}
    </div>
  </div>
</div>

그리고 해당 각도 컨트롤러.

function AngularCtrl($scope) {
    $scope.predicate = 'score';
    $scope.reverse = true;
    $scope.users = [{id: 1, name: 'John'}, {id: 2, name: 'Ken'}, {id: 3, name: 'smith'}, {id: 4, name: 'kevin'}, {id: 5, name: 'bob'}, {id: 6, name: 'Dev'}, {id: 7, name: 'Joe'}, {id: 8, name: 'kevin'}, {id: 9, name: 'John'}, {id: 10, name: 'Ken'}, {id: 11, name: 'John'}, {id: 1, name: 'John'}, {id: 2, name: 'Ken'}, {id: 3, name: 'smith'}, {id: 4, name: 'kevin'}, {id: 5, name: 'bob'}, {id: 6, name: 'Dev'}, {id: 7, name: 'Joe'}, {id: 8, name: 'kevin'}, {id: 9, name: 'John'}, {id: 10, name: 'Ken'}]
}

위의 코드를 실행하면 오류 : 10 $ digest () 반복에 도달했습니다. 중단 중! 내 콘솔에 오류가 있습니다.

동일한 jsfiddle 을 만들었습니다 .

정렬 술어는 ng-repeat 내에서만 초기화되고 한계도 오브젝트 수에 적용됩니다. sortby와 limitTo 감시자를 함께 사용하는 것이 오류의 원인이라고 생각합니다.

$ scope.reverse가 false (점수 오름차순) 인 경우 오류가 발생하지 않습니다.

아무도 내가 여기서 무엇이 잘못되었는지 이해하도록 도울 수 있습니까? 당신의 도움에 감사드립니다.


if 문을 제거해도 여전히 오류가 발생합니까?
Mathew Berg

귀하의 답변 Mathew에 감사드립니다! 문제를 잘못 진단했습니다. 문제는 sortby 및 limitTo 필터와 관련이있는 것 같습니다. JSFiddle로 질문을 업데이트했습니다. 당신의 도움에 감사드립니다.
Chubby Boy

이것은 각도입니다. 함수를 기억하고 상태를 기억해야합니다. 내 대답을 잡아 stackoverflow.com/questions/14376879/...
훌리오 마린에게

답변:


116

jsFiddle을 확인하십시오 . (코드는 기본적으로 게시 한 것과 동일하지만 스크롤 이벤트를 바인딩하기 위해 창 대신 요소를 사용합니다).

내가 볼 수있는 한, 게시 한 코드에는 아무런 문제가 없습니다. 언급 한 오류는 일반적으로 속성에 대한 변경 루프를 만들 때 발생합니다. 예를 들어 특정 속성의 변경 사항을 관찰 한 다음 리스너에서 해당 속성의 값을 변경하는 경우와 같이 :

$scope.$watch('users', function(value) {
  $scope.users = [];
});

오류 메시지가 나타납니다.

잡히지 않는 오류 : 10 $ digest () 반복에 도달했습니다. 중단 중!
지난 5 번의 반복에서 해고 된 사람들 : ...

코드에 이런 종류의 상황이 없는지 확인하십시오.

최신 정보:

이것이 당신의 문제입니다 :

<div ng-init="user.score=user.id+1"> 

렌더링하는 동안 객체 또는 모델을 변경해서는 안되며 그렇지 않으면 새로운 렌더링을 강제로 수행합니다 (결과적으로 루프 원인, '도달 중단 10 $ 소화 () 반복. 오류!' ).

모델을 업데이트하려면 뷰에서 절대로 컨트롤러 나 지시문에서 수행하지 마십시오. angularjs 문서 는 사용하지 않는 것이 좋습니다ng-init 이런 상황을 방지하기 위해 정확히를 :

템플릿에서 ngInit 지시문 사용

다음 은 실제 예제 가 포함 된 jsFiddle 입니다.


1
참고로 대신 angular.element(w).bind()사용할 수 있습니다 element.bind().
Mark Rajcok

많은 bmleite와 Mark에게 감사드립니다. 문제를 잘못 진단했습니다. 위의 의견을 참조하십시오. JSFiddle로 질문을 업데이트했습니다. 당신의 도움에 감사드립니다.
통통한 소년

@bmleite 대단히 감사합니다! 더 많은 것을 이해하려고 노력합니다. 그러나 왜 $ scope.reverse = false (점수 오름차순)로 오류가 발생하지 않습니까?
Chubby Boy

오름차순 및 내림차순에는 접두사 '+'및 '-'를 각각 사용해야합니다 (예 : '+ score'및 '-score'). 이에 대한 자세한 내용은 여기를 참조하십시오 .
bmleite

1
이 답변은 내 문제를 해결했습니다. 설명은 문제를 설명한다는 점에서 좋습니다. $ digest () 반복 오류는 루핑하는 동안 속성을 수정하려고 할 때 발생합니다. 따라서 각 속성 변경은 뷰 (UI) 업데이트를 트리거하고 각도는 결국 10 루프에서 최대가됩니다. jsFiddle 예제는 속성 변경을 컨트롤러에 넣습니다. 보기에서 속성을 변경하면이 오류가 발생합니다.
mbokil

9

나를 위해이 오류의 원인은 ...

ng-if="{{myTrustSrc(chat.src)}}"

내 템플릿에

컨트롤러의 myTrustSrc 함수가 무한 루프에서 호출됩니다. 이 줄에서 ng-if를 제거하면 문제가 해결됩니다.

<iframe ng-if="chat.src" id='chat' name='chat' class='chat' ng-src="{{myTrustSrc(chat.src)}}"></iframe>

ng-if를 사용하지 않으면 함수는 몇 번만 호출됩니다. ng-src로 왜 함수가 두 번 이상 호출되는지 궁금합니다.

이것은 컨트롤러의 기능입니다

$scope.myTrustSrc = function(src) {
    return $sce.trustAsResourceUrl(src);
}

ng-src로 왜 함수가 두 번 이상 호출되는지 궁금합니다. -각도는 동일한 2 개의 결과를 얻을 때까지 html을 몇 번 만들려고하기 때문에. 그것은 10 $ digest () 반복에 도달 한 오류의 의미입니다. 그는 10 번 시도했지만 2 개의 동일한 결과를
얻지 못했습니다

@bresleveloper이 정보와 링크를 제공 할 수 있습니까? 감사.
Willa

@Willa here docs.angularjs.org/api/ng/type/$rootScope.Scope CTRF + F this "재실행 반복 제한은 무한 루프 교착 상태를 방지하기 위해 10입니다"
bresleveloper

감사. 도움이되었습니다.
Willa

7

나를 위해 매번 새로운 객체를 생성하는 지시문에 2-way 바인딩 입력 '='으로 함수 결과를 전달하고있었습니다.

그래서 나는 그런 것을 가지고 있었다 :

<my-dir>
   <div ng-repeat="entity in entities">
      <some-other-dir entity="myDirCtrl.convertToSomeOtherObject(entity)"></some-other-dir>
   </div>
</my-dir>

my-dir의 컨트롤러 방법은

this.convertToSomeOtherObject(entity) {
   var obj = new Object();
   obj.id = entity.Id;
   obj.value = entity.Value;
   [..]
   return obj;
}

내가 할 때

this.convertToSomeOtherObject(entity) {
   var converted = entity;
   converted.id = entity.Id;
   converted.value = entity.Value;
   [...]
   return converted;
}

문제를 해결했다!

잘하면 이것은 누군가를 도울 것입니다 :)


5

이 문제를 일으킨 또 다른 예가 있습니다. 앞으로 참고할 수 있기를 바랍니다. AngularJS 1.4.1을 사용하고 있습니다.

사용자 지정 지시문을 여러 번 호출 하여이 마크 업이 발생했습니다.

<div ng-controller="SomeController">
    <myDirective data="myData.Where('IsOpen',true)"></myDirective>
    <myDirective data="myData.Where('IsOpen',false)"></myDirective>
</div>

myData 배열이며 Where() IsOpen 속성이 두 번째 매개 변수의 bool 값과 일치하는 원본 항목을 포함하는 새 배열을 반환하는 배열을 반복하는 확장 메서드입니다.

컨트롤러에서 다음 $scope.data과 같이 설정 했습니다.

DataService.getData().then(function(results){
    $scope.data = results;
});

Where()위의 마크 업과 같이 지시문에서 확장 메소드를 호출하는 것이 문제였습니다. 이 문제를 해결하기 위해 마크 업 대신 확장 메소드에 대한 호출을 컨트롤러로 옮겼습니다.

<div ng-controller="SomeController">
    <myDirective data="openData"></myDirective>
    <myDirective data="closedData"></myDirective>
</div>

그리고 새로운 컨트롤러 코드 :

DataService.getData().then(function(results){
    $scope.openData = results.Where('IsOpen',true);
    $scope.closedData = results.Where('IsOpen',false);
});

그것은 내가 가진 문제와 정확히 같습니다. 아무것도 업데이트하지 않고 로컬 배열을 생성하고 하나의 기존 $ scope 배열을 반복하고 로컬 배열에서 객체를 생성하여 반환하는 간단한 함수입니다. 한 번만 호출하여 $ scope 멤버에 저장하면 문제가 해결됩니다. 감사. 방법을 직접 사용하는 데 문제가 있다는 것을 알고 싶습니다.
AgilePro가

2

파티에 꽤 늦었지만 각도 1.5.8의 UI 라우터에 결함이 있기 때문에 문제가 발생했습니다. 언급 할 것은이 오류는 응용 프로그램을 처음 실행할 때만 나타 났으며 나중에 다시 발생하지 않는다는 것입니다. github 의이 게시물 은 내 문제를 해결했습니다. 기본적으로 오류는 $urlRouterProvider.otherwise("/home") 다음과 같습니다. 솔루션은 다음과 같은 해결 방법이었습니다.

$urlRouterProvider.otherwise(function($injector, $location) {
   var $state = $injector.get("$state");
   $state.go("your-state-for-home");
});

2

우선 모든 대답을 무시하고 $ watch를 사용하도록 지시하십시오. Angular는 이미 리스너에서 작동합니다. 나는 단지 당신이이 방향으로 생각함으로써 사물을 복잡하게 만들고 있음을 보증합니다.

$ timeout 사용자에게 알려주는 모든 대답을 무시하십시오. 페이지를로드하는 데 걸리는 시간을 알 수 없으므로 이것이 최선의 해결책은 아닙니다.

페이지 렌더링이 완료된 시점 만 알면됩니다.

<div ng-app='myApp'>
<div ng-controller="testctrl">
    <label>{{total}}</label>
    <table>
      <tr ng-repeat="item in items track by $index;" ng-init="end($index);">
        <td>{{item.number}}</td>
      </tr>
    </table>
</div>

var app = angular.module('myApp', ["testctrl"]);
var controllers = angular.module("testctrl", []);
 controllers.controller("testctrl", function($scope) {

  $scope.items = [{"number":"one"},{"number":"two"},{"number":"three"}];

  $scope.end = function(index){
  if(index == $scope.items.length -1
        && typeof $scope.endThis == 'undefined'){

            ///  DO STUFF HERE
      $scope.total = index + 1;
      $scop.endThis  = true;
 }
}
});

$ index로 ng-repeat를 추적하고 배열의 길이가 index와 같을 때 루프를 멈추고 논리를 수행하십시오.

jsfiddle


1

각도 트리 제어의 맥락 에서이 오류가 발생했습니다. 제 경우에는 트리 옵션이었습니다. 함수에서 treeOptions ()를 반환했습니다. 항상 같은 객체를 반환했습니다. 그러나 Angular는 마 법적으로 새로운 물체라고 생각하고 다이제스트 사이클을 시작합니다. 다이제스트 재귀를 유발합니다. 해결책은 treeOptions를 범위에 바인딩하는 것이 었습니다. 그리고 한 번만 할당하십시오.


1

이상합니다 ... 다른 것에서 나온 것과 동일한 오류가 발생했습니다. 컨트롤러를 만들 때 $ location 매개 변수를 다음과 같이 전달했습니다.

App.controller('MessageController', function ($scope, $http, $log, $location, $attrs, MessageFactory, SocialMessageFactory) {
   // controller code
});

이것은 버그 로 입증되었습니다 타사 라이브러리 또는 순수 JS를 사용하여 일부 특정 항목 (여기서는 window.location)을 조작 할 때 . 다음 각도 요약에서는이 오류가 발생합니다.

따라서 컨트롤러 생성 매개 변수에서 $ location 을 제거 하고이 오류없이 다시 작동했습니다. 또는 angular에서 $ location을 절대적으로 사용해야하는 경우 <a href="#">link</a>템플릿 페이지의 링크에서 모든 단일 항목을 제거하고 href = ""를 작성해야 합니다. 나를 위해 일했다.

그것이 언젠가 도울 수 있기를 바랍니다.



0

Firefox를 버전 51로 업그레이드 한 직후에이 clearing the cache문제가 발생했습니다 . 이후 문제가 해결되었습니다.


0

내가 정의했기 때문에 비슷한 오류가 발생했습니다.

ng-class = "GetLink ()"

대신에

ng-click = "GetLink ()"


0

이것은 ng-src에서 호출 된 함수의 반환 값으로 $ sce.trustAsResourceUrl ()을 사용할 때 각도 1.6-> 1.7에서 업그레이드 한 후에 나에게 발생했습니다. 여기에 언급 된이 문제를 볼 수 있습니다 .

내 경우에는 다음을 변경해야했습니다.

<source ng-src="{{trustSrc(someUrl)}}" type='video/mp4' />
trustSrc = function(url){
    return $sce.trustAsResourceUrl(url);
};

<source ng-src='{{trustedUrl}} type='video/mp4' />
trustedUrl = $sce.trustAsResourceUrl(someUrl);

0

사용자 정의 정렬 필터에서 Array.reverse ()를 호출 할 때 AngularJS 1.3.9를 사용하는 것과 동일한 오류가 발생했습니다.

그것을 제거한 후에는 잘 팔립니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.