1. ホーム
  2. angularjs

[解決済み] ng-repeatで関数が返す項目をループスルーするには?

2022-09-07 17:57:45

質問

divを繰り返し作成したいのですが、アイテムは関数から返されるオブジェクトです。しかし、次のコードはエラーを報告します。 10 $digest()反復に達した。中止! jsfiddleはこちらです。 http://jsfiddle.net/BraveOstrich/awnqm/

<body ng-app>
  <div ng-repeat="entity in getEntities()">
    Hello {{entity.id}}!
  </div>
</body>

どのように解決するのですか?

短い答え : 本当にそのような関数が必要なのですか? http://jsfiddle.net/awnqm/1/

長い回答

シンプルにするために、あなたのケース(オブジェクトの配列に対するngRepeat)だけを説明します。また、私はいくつかの詳細を省略します。

AngularJSでは ダーティチェック を使用しています。アプリケーションが起動されると $digest に対して $rootScope . $digest に対して深さ優先の探索を行います。 スコープの階層 . すべてのスコープはウォッチのリストを持っています。各ウォッチは最後の値(最初は initWatchVal ). 各スコープですべてのウォッチに対して $digest はそれを実行し、現在の値を取得します ( watch.get(scope) ) と比較し watch.last . もし現在の値が watch.last と等しくない場合 (常に最初の比較のために) $digest セット dirtytrue . すべてのスコープが処理されたとき、もし dirty == true $digest から別の深さ優先探索を開始します。 $rootScope . $digest は、dirty == false または traversals の数 == 10 のときに終了します。後者の場合、エラー "10 $digest() iterations reached." がログに記録されます。

では ngRepeat . それぞれの watch.get を呼び出すと、コレクションからオブジェクトが格納されます。 getEntities を返す)、キャッシュの追加情報( HashQueueMap によって 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回トラバースすると、エラーが発生します。

どのようにそれを修正することができますか

  1. 新しいオブジェクトをすべての getEntities() を呼び出すたびに新しいオブジェクトを作成しないようにします。
  2. 新しいオブジェクトを作成する必要がある場合には hashKey メソッドを追加します。参照 このトピック を参照してください。

AngularJSの内部を知っている人が、私が何か間違っていたら訂正してくれることを願っています。