短い答え:本当にそのような機能が必要ですか、それともプロパティを使用できますか? http://jsfiddle.net/awnqm/1/
長い答え
簡単にするために、オブジェクトの配列の ngRepeat のケースのみを説明します。また、一部省略させていただきます。
AngularJS は、ダーティ チェックを使用して変更を検出します。アプリケーションが開始されると、 に対して実行$digest
され$rootScope
ます。スコープの階層$digest
に対して深さ優先のトラバーサルを行います。すべてのスコープには、ウォッチのリストがあります。各時計には最後の値があります (最初は)。すべてのウォッチのスコープごとに実行し、現在の値 ( ) を取得して と比較します。現在の値が等しくない場合(常に最初の比較の場合)に設定されます。すべてのスコープが処理されると、から別の深さ優先トラバーサルが開始されます。ダーティ == false またはトラバーサル数 == 10 の場合に終了します。後者の場合、「10 回の $digest() 反復に達しました」というエラーが発生します。記録されます。initWatchVal
$digest
watch.get(scope)
watch.last
watch.last
$digest
dirty
true
dirty == true
$digest
$rootScope
$digest
今約ngRepeat
。呼び出しごとwatch.get
に、コレクションからのオブジェクト ( の戻り値getEntities
) を追加情報とともにキャッシュ ( HashQueueMap
by hashKey
) に格納します。watch.get
呼び出しごとに、キャッシュからngRepeat
オブジェクトを取得しようとします。hashKey
キャッシュに存在しない場合は、キャッシュにngRepeat
保存し、新しいスコープを作成し、オブジェクトを配置し、DOM 要素を作成します。
今約hashKey
。通常hashKey
は によって生成される一意の番号nextUid()
です。しかし、それは関数にすることができます。hashKey
生成後、将来の使用のためにオブジェクトに格納されます。
あなたの例がエラーを生成する理由: 関数getEntities()
は常に新しいオブジェクトを含む配列を返します。このオブジェクトはキャッシュhashKey
に存在せず、存在しません。ngRepeat
そのためngRepeat
、それぞれwatch.get
が new watch for を使用して新しいスコープを生成し{{entity.id}}
ます。この時計は最初watch.get
に を持っていwatch.last == initWatchVal
ます。だからwatch.get() != watch.last
。というわけ$digest
で新たなトラバース開始。そのngRepeat
ため、新しいウォッチで新しいスコープを作成します。だから... 10回のトラバースの後、エラーが発生します。
修正方法
getEntities()
呼び出しごとに新しいオブジェクトを作成しないでください。
- 新しいオブジェクトを作成する必要がある場合は
hashKey
、それらのメソッドを追加できます。例については、このトピックを参照してください。
私が何か間違っている場合は、AngularJS の内部を知っている人が私を訂正してくれることを願っています。