141

ユーザーの名前とスコアを繰り返して表示する次のコードがあります。

<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 (スコアの昇順) の場合、エラーにはなりません。

ここで何が間違っているのかを理解してくれる人はいますか? どうもありがとうございました。

4

13 に答える 13

117

このjsFiddleを確認してください。(コードは基本的にあなたが投稿したものと同じですが、ウィンドウの代わりに要素を使用してスクロール イベントをバインドします)。

私が見る限り、あなたが投稿したコードに問題はありません。あなたが言及したエラーは、通常、プロパティに対する変更のループを作成するときに発生します。たとえば、特定のプロパティの変更を監視し、リスナーでそのプロパティの値を変更する場合のように:

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

これにより、次のエラー メッセージが表示されます。

キャッチされないエラー: 10 回の $digest() 反復に達しました。中止します!
最後の 5 回の繰り返しで発生したウォッチャー: ...

コードにこの種の状況がないことを確認してください。

アップデート:

これはあなたの問題です:

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

レンダリング中にオブジェクト/モデルを変更しないでください。そうしないと、新しいレンダリングが強制されます (その結果、ループが発生し、「エラー: 10 回の $digest() 反復に達しました。中止!」が発生します)。

モデルを更新する場合は、コントローラーまたはディレクティブで行い、決してビューでは行いません。angularjs のドキュメントでは、これらの種類の状況を回避するために、正確に使用しないことを推奨しています。ng-init

テンプレートで ngInit ディレクティブを使用します (おもちゃ/サンプル アプリのみ。実際のアプリケーションには推奨されません)。

これは、実際の例を含むjsFiddleです。

于 2013-01-17T14:37:52.113 に答える
7

私にとっては、関数の結果を、毎回新しいオブジェクトを作成するディレクティブに双方向バインディング入力 '=' として渡していたということでした。

だから私はそのようなものを持っていました:

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

問題を解決しました!

うまくいけば、これは誰かを助けるでしょう:)

于 2016-03-23T17:41:59.427 に答える
5

これを引き起こした別の例があります。今後の参考になれば幸いです。AngularJS 1.4.1 を使用しています。

カスタム ディレクティブへの複数の呼び出しを含むこのマークアップがありました。

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

myDataWhere()IsOpen プロパティが 2 番目のパラメーターの 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);
});
于 2015-06-25T17:13:52.347 に答える
2

パーティーにはかなり遅れましたが、angular 1.5.8 の ui-router に欠陥があるため、私の問題が発生していました。言及すべきことは、このエラーはアプリケーションを初めて実行したときにのみ表示され、その後は再発しないということです. このgithubからの投稿は私の問題を解決しました。基本的にエラーには以下が含まれます$urlRouterProvider.otherwise("/home") 。解決策は次のような回避策でした。

$urlRouterProvider.otherwise(function($injector, $location) {
   var $state = $injector.get("$state");
   $state.go("your-state-for-home");
});
于 2018-03-09T15:20:14.163 に答える
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 を追跡し、配列の長さがインデックスと同じになったら、ループを停止してロジックを実行します。

jsfiddle

于 2016-09-20T17:06:16.163 に答える
1

奇妙です...別のものから来て、まったく同じエラーが発生しました。コントローラーを作成するときに、次のように $location パラメーターを渡しました。

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

これは、サードパーティのライブラリまたは純粋な JS を使用していくつかの詳細 (ここでは window.location) を操作するときにバグであることが証明されており、 Angular の次のダイジェストでこのエラーが発生します。

したがって、コントローラー作成パラメーターから$locationを削除しただけで、このエラーなしで再び機能しました。または、Angular の $location を絶対に使用する必要がある場合は<a href="#">link</a>、テンプレート ページのリンクをすべて削除し、href=""と記述する必要があります。私のために働いた。

いつか役立つことを願っています。

于 2015-06-25T12:38:53.840 に答える
0

定義したため、同様のエラーが発生しました

ng-class="GetLink()"

それ以外の

ng-click="GetLink()"

于 2017-03-11T10:07:53.317 に答える
0

angular を使用する場合は、ブラウザー コンソールから ng-storage プロファイルを削除します。これは一般的な解決策ではありませんが、私の場合はうまくいきました。

Chrome F12->リソース->ローカルストレージ

于 2016-07-27T11:55:25.837 に答える
0

これは、ang-src から呼び出される関数の戻り値として $sce.trustAsResourceUrl() を使用するときに、angular 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);
于 2018-10-09T15:32:01.267 に答える