答え
$scope.$watch('$viewContentLoaded',
function() {
$timeout(function() {
//do something
},0);
});
私がテストしたほとんどのシナリオで機能するのはこれだけです。テンプレートからHTMLを構築する4つのコンポーネントを持つサンプルページでは、イベントの順序は
$document ready
$onInit
$postLink
(and these 3 were repeated 3 more times in the same order for the other 3 components)
$viewContentLoaded (repeated 3 more times)
$timeout execution (repeated 3 more times)
したがって、$ document.ready()は、angularで構築されているDOMが準備ができていない可能性があるため、ほとんどの場合役に立たない。
しかし、もっと興味深いのは、$ viewContentLoadedが発生した後でも、関心のある要素がまだ見つからなかったことです。
$ timeoutが実行された後にのみ、それが見つかりました。$ timeoutの値が0であっても、実行までに約200ミリ秒が経過しているため、このスレッドがしばらく(おそらくDOMがメインスレッドに角度テンプレートを追加している間)保留されていたことを示しています。最初の$ document.ready()から最後の$ timeoutの実行までの合計時間は、ほぼ500ミリ秒でした。
コンポーネントの値が設定され、text()値が後で$ timeoutで変更された1つの異常なケースでは、$ timeout値は、それが機能するまで増加する必要がありました(ただし、$ timeout中に要素が見つかった場合でも) )。サードパーティコンポーネント内で非同期の何かが発生したため、十分な時間が経過するまで、値がテキストよりも優先されました。別の可能性は$ scope。$ evalAsyncですが、試行されませんでした。
私はまだ、DOMが完全に落ち着いており、すべてのケースが機能するように操作できることを通知する1つのイベントを探しています。これまでのところ、任意のタイムアウト値が必要です。これは、せいぜい遅いブラウザでは機能しない可能性があることを意味します。私はliveQueryやパブリッシュ/サブスクライブのようなJQueryオプションを試したことはありませんが、確かに純粋なものではありません。