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

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

<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 (점수 오름차순) 인 경우 오류가 발생하지 않습니다.

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



답변

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 입니다.


답변

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

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);
}


답변

나를 위해 매번 새로운 객체를 생성하는 지시문에 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;
}

문제를 해결했다!

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


답변

이 문제를 일으킨 또 다른 예가 있습니다. 앞으로 참고할 수 있기를 바랍니다. 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);
});


답변

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

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


답변

우선 모든 대답을 무시하고 $ 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


답변

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