I've done extensive research on this subject, but no matter what I do, I find it extremely difficult to achieve this objective.
I want to execute code when all elements have been fully rendered in AngularJS web application. I think I found solution suggesting to use routers and views, but I could not make that work on my case, as it seems it requires certain configuration.
When you have ng-repeat
and a lot of nested directives
that will generate HTML/Content based on various conditions using ng-if
, I noticed that HTML rendering continues even after document ready event is fired or view content have been loaded ie $viewContentLoaded
event is triggered.
The closest idea I have is to use $watch
over the length of the children of the element of a given directive
. Every time the $watch
is executed, increment counter renderCount
. Then, in another timer event, check if the counter renderCount
didn't change over the past say 3-5 seconds, then we can make an assumption that rendering is done.
The code to watch for the children, and check if no more rendering is taking place, could be as follows:
app.directive('whenRenderingDone', function($interval, $parse){
return {
link: function (scope, el, attrs) {
var renderingCount = 0;
function watchForChildren() {
scope.$watch(function(){
return $(':input', el).length;
}, function(newVal, oldVal){
if (newVal) {
renderingCount++;
}
})
}
watchForChildren();
//Check counter every 3 seconds, if no change since last time, this means rendering is done.
var checkRenderingDone = $interval(function(){
var lastCount = lastCount || -1;
if (lastCount === renderingCount) {
var func = $parse(attrs.whenRenderingDone);
$interval.cancel(checkRenderingDone);
func(scope);
}
lastCount = renderingCount || -1;
}, 3000);
}
}
});
I will try to implement the above approach, and if you have feedback please let me know.
Tarek