ngRepeatFinishedが動かなかったので修正した話(AngularJS)
DOM操作の都合上、AngularJSのループ処理のngRepeatのレンダリングが終わった時の イベントが拾いたい時が結構ある。
そこでよく見る解決策が、「onFinishRender」やら「ngRepeatFinished」という言葉
色んな所で(StackOverflowとか、海外のブログとか)で見かける方法なので、正直何も疑問に 思わず使っていたが、ちょっとハマってしまった。
ngRepeatディレクティブの「$last」プロパティを使い、最後データの場合「$last」がtrueになるため、 $emitが動作し(イベント登録していれば)Controllerが動作する仕組み。
これをngRepeat + Filterを合わせて使用すると、期待通りに動かなかった。
Filterの条件によってngRepeatで描画するデータが変化するたびに「ngRepeatFinished」イベントを投げるだろうと思っていたけど 全然イベントが発生しなかった。
色々情報を探したところ、onFinishRenderを使いつつ、正常に動作しないコード例を見つけた。
onFinishRender not called - emit
↓自分好みにちょっと書き直し
最後のデータの文字列を「赤文字」にするために「ngRepeatFinished」イベントを利用している。
検索条件に「40」を入力るすと、最後の文字が「赤文字」ではなく「黒文字」で表示されてしまう。
結論を書いてしまうと、ngRepeatディレクティブの「$last」をバインド(値の変更の監視)をやっていないため起きていた。
フィルタ条件がない状態で、全データを描画した時は、各行で「ngRepeatFinished」の「link」を実行し、 最後のデータは「$last」がtrueになるため、最後のデータの文字列が「赤文字」になる。
その後、フィルタの条件を指定しても、各行で「ngRepeatFinished」の「link」が実行されないし、 「$last」を$watchしていないため、「ngRepeatFinished」を投げるタイミングがなくなっていた。
↓修正バージョン
検索条件に「40」を入力しても、コチラは更新されるようになっている。