2016-05-23 9 views
1

immer diese Fehlermeldung erreicht: Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!

ich einen reddit Stil verschachtelten Kommentarsystem mit AngularJS erstellt haben. Aber nach 10 Ebene tief ich einen sehr hässlichen Fehler auf meiner Konsole erhalten, die wie folgt aussieht:

enter image description here

Das nach dem Tief genau 10 Stufen passiert:

enter image description here

Die verschachtelten Kommentare Richtlinien sind dass sieht wie folgt aus:

commentCont.tpl.html:

<div class="comment-cont"> 
    <div 
     class="upvote-arrow" 
     ng-show="!collapsed" 
     ng-click="vote()" 
     ng-class="{'active' : node.votedByMe}" 
    > 
     <div class="upvote-arrow-top"></div> 
     <div class="upvote-arrow-bottom"></div>   
    </div>  
    <div class="wrapper"> 
     <div class="info"> 
      <span class="collapse" ng-click="collapsed = !collapsed">[ {{collapsed ? '+' : '–'}} ]</span> 
      <span ng-class="{'collapsed-style' : collapsed}"> 
       <a ui-sref="main.profile({id: node.userId})">{{node.username}}</a> 
       <span>{{node.upvotes}} point{{node.upvotes != 1 ? 's' : ''}}</span> 
       <span mg-moment-auto-update="node.createdTime"></span> 
       <span ng-show="collapsed">({{node.children.length}} child{{node.children.length != 1 ? 'ren' : ''}})</span> 
      </span> 
     </div>   
     <div class="text" ng-bind-html="node.comment | autolink | nl2br" ng-show="!collapsed"></div> 
     <div class="reply" ng-show="!collapsed"> 
      <span ng-click="formHidden = !formHidden">reply</span> 
     </div>   
    </div> 
    <div class="input-area" ng-show="!collapsed"> 
     <form ng-show="!formHidden" name="form" autocomplete="off" novalidate ng-submit="submitted = true; submit(formData, form)"> 

      <div class="form-group comment-input-feedback-branch has-error" ng-show="form.comment.$invalid && form.comment.$dirty"> 
       <div ng-messages="form.comment.$error" ng-if="form.comment.$dirty"> 
        <div class="input-feedback" ng-message="required">Comment text is required.</div> 
        <div class="input-feedback" ng-message="maxlength">Comment text cannot exceed 2500 characters.</div> 
       </div> 
      </div> 

      <div 
       class="form-group" 
       ng-class="{ 'has-error' : form.comment.$invalid && form.comment.$dirty, 'has-success' : form.comment.$valid }" 
      > 
       <textarea 
        name="comment" 
        class="textarea comment-cont-textarea" 
        ng-model="formData.comment" 
        required 
        ng-maxlength="2500" 
        textarea-autoresize 
       ></textarea> 
      </div> 
      <div class="form-group"> 
       <mg-button-loading 
        mgbl-condition="awaitingResponse" 
        mgbl-text="Save" 
        mgbl-loading-text="Saving..." 
        mgbl-class="btn-blue btn-small" 
        mgbl-disabled="!form.$valid" 
       ></mg-button-loading> 
       <mg-button-loading 
        mgbl-text="Cancel" 
        mgbl-class="btn-white btn-small" 
        ng-click="formHidden=true;" 
       ></mg-button-loading> 
      </div>     
     </form> 
    </div> 
    <div ng-show="!collapsed"> 
     <div ng-repeat="node in node.children" ng-include="'commentTree'"></div> 
    </div> 
</div> 

commentCont.directive.js:

<script type="text/ng-template" id="commentTree"> 
    <comment-cont 
     node="node" 
    ></comment-cont> 
</script> 
<div ng-repeat="node in tree[0].children" ng-include="'commentTree'"></div> 

Wie kann ich mehr als 10 Ebenen von verschachtelten ng-repeat haben, ohne wie dies auf einen Fehler zu bekommen:

(function() { 
    'use strict'; 

    angular 
     .module('app') 
     .directive('commentCont', commentCont); 

    /* @ngInject */ 
    function commentCont ($http, user, $timeout) { 

     return { 
      restrict: 'E', 
      replace: true, 
      scope: { 
       node: '=' 
      }, 
      templateUrl: 'app/post/commentCont.tpl.html', 
      link: function (scope, element, attrs) { 

       var textarea = element.querySelector('.comment-cont-textarea'); 
       var voteOK = true; 
       var action = ''; 

       var userInfo = user.get(); 

       scope.formHidden = true; // Do not ng-init="" inside an ng-repeat. 
       scope.collapsed = false; // Do not ng-init="" inside an ng-repeat. 

       // Autofocus textarea when reply link is clicked. 
       scope.$watch('formHidden', function(newValue, oldValue) { 
        if (newValue !== true) { 
         $timeout(function() { 
          textarea[0].focus(); 
         });      
        } 
       }); 

       scope.submit = function (formData, form) { 
        if (form.$valid) { 
         scope.awaitingResponse = true; 
         formData.parentId = scope.node.id; 
         formData.postId = scope.node.postId; 

         formData.type = 4; 
         formData.fromUsername = userInfo.username; 
         formData.toId = scope.node.userId; 
         formData.fromImage = userInfo.thumbnail36x36.split('/img/')[1]; 

         // console.log(formData); 

         $http.post('/api/comment', formData) 
          .then(function (response) { 
           scope.awaitingResponse = false; 

           if (response.data.success) { 
            if (response.data.rateLimit) { 
             alert(rateLimitMessage); 
             return false; 
            } 
            // id and createdTime is sent with response.data.comment. 
            var c = response.data.comment; 
            var newCommentNode = { 
             id: c.id, 
             userId: userInfo.id, 
             username: userInfo.username, 
             parentId: formData.parentId, 
             comment: formData.comment, 
             upvotes: 0, 
             createdTime: c.createdTime, 
             votedByMe: false, 
             children: [], 
             postId: scope.node.postId 
            }; 
            // console.log('user', user.get()); 
            // console.log('scope.node', scope.node); 
            // console.log('response', response); 
            // console.log('newCommentNode', newCommentNode); 
            formData.comment = ''; 
            form.comment.$setPristine(); 
            scope.formHidden = true; 
            scope.node.children.unshift(newCommentNode);          
           } 
          }); 
        } 
       }; 

       scope.vote = function() { 
        if (voteOK) { 
         voteOK = false; 
         if (!scope.node.votedByMe) { 
          scope.node.votedByMe = true; 
          action = 'add'; 
         } else { 
          scope.node.votedByMe = false; 
          action = 'remove'; 
         } 
         var data = { 
          commentId: scope.node.id, 
          action: action 
         }; 
         $http.post('/api/comment/vote', data) 
          .then(function (response) { 
           // console.log(response.data); 
           voteOK = true; 
           if (action === 'add') { 
            scope.node.upvotes++; 
           } else { 
            scope.node.upvotes--; 
           } 
          });      
        } 
       }; 
      } 
     }; 
    } 

}()); 

Der Baum wie folgt aufgerufen wird ?

+0

Das ist nicht wirklich eine Option, da ich bereits nur relevante Teile habe. – Alex

Antwort

2

Die Standardimplementierung von $ digest() hat ein Limit von 10 Iterationen. Wenn der Bereich nach 10 Iterationen immer noch schmutzig ist, wird der Fehler aus $ digest() ausgelöst.

den unten angegebenen ist eine Möglichkeit, die Grenze von verdauen Iterationen bis 20 der Konfiguration

var app = angular.module('plunker', [], function($rootScopeProvider) { 
    $rootScopeProvider.digestTtl(20); // 20 being the limit of iterations. 
}); 

Aber Sie sollten eher zur Stabilisierung Ihr Modell aussehen in als die Grenze von Iterationen konfigurieren.

+1

Danke! Ich musste nur 21 Levels machen. – Alex

+1

Danke, ich hatte die gleiche Art von Problem. Das gibt mir jetzt eine schnelle Lösung, bis ich die Zeit habe, umzuschreiben. – Pjetr

Verwandte Themen