如何检测在AngularJS中完成HTML渲染的时间 [英] How can you detect when HTML rendering is completed in AngularJS
问题描述
我在这方面做了大量研究,但无论我做什么,我都觉得实现这个目标非常困难。
当所有元素已经在AngularJS Web应用程序中完全呈现时。我认为我找到的解决方案建议使用路由器和视图,但我无法对我的案例做出这项工作,因为它似乎需要特定的配置。当您有 ng-repeat
和大量嵌套的指令
,它们将根据各种条件使用 ng-if
,我注意到即使在文档就绪事件被触发或视图内容已经被加载后,HTML渲染仍然继续,即触发 $ viewContentLoaded
事件。
我最近的想法是在元素的子元素长度上使用 $ watch
给定指令
。每次执行 $ watch
时,都会增加计数器 renderCount
。然后,在另一个计时器事件中,检查计数器 renderCount
过去是否改变了3-5秒,然后我们可以假设渲染已完成。 / p>
观察孩子的代码,并检查是否没有更多渲染发生,可能如下所示:
app.directive('whenRenderingDone',function($ interval,$ parse){
return {
link:function(scope,el,attrs){
var renderingCount = 0;
函数watchForChildren(){$ b $ scope。$ watch(function(){
return $(':input',el).length; $ b $ (newVal){
renderingCount ++;
}
})
}
watchForChildren();函数(newVal,oldVal){
b $ b //每3秒检查一次计数器,如果自上次没有变化,则表示渲染克完成。
var checkRenderingDone = $ interval(function(){
var lastCount = lastCount || -1;
if(lastCount === renderingCount){
var func = $ parse(
$ interval.cancel(checkRenderingDone);
func(scope);
}
lastCount = renderingCount || -1;
},3000 );
}
}
});
我会尝试实施上述方法,如果您有任何意见,请告诉我们。
Tarek
和IE11:
app.directive('whenRenderingDone',function($ timeout,$ parse){
return {
link:function(scope,el,attrs){
var lastCount;
var lastTimer = 5000; //初始超时
//每隔几秒检查计数器,如果没有更改
var checkRenderingDone = function(){
var mainPromiseResolved = scope.mainPromiseResolved;
lastCount = lastCount || -1;
if( lastCount === el.find('*').length&& mainPromiseResolved){
console.log('Rendering done,lastCount =%i',lastC ount);
var func = $ parse(attrs.whenRenderingDone);
func(scope);
} else {
lastCount = el.find('*')。length;
console.log('mainPromiseResolved =%s,lastCount%i',mainPromiseResolved,lastCount)
console.log('渲染尚未完成,%i秒后再次检查',lastTimer / 1000.00) ;
stopCheckRendering = $ timeout(checkRenderingDone,lastTimer);
lastTimer = lastTimer - 1000;
if(lastTimer< = 0){
lastTimer = 1000;
}
return stopCheckRendering;
}
}
var stopCheckRendering;
stopCheckRendering = checkRenderingDone();
el.on('$ destroy',function(){
if(stopCheckRendering){
$ timeout.cancel(stopCheckRendering);
}
});
}
}
});
我希望这对您有所帮助,如果您有任何改进意见,请让我知道。 查看这个给你一个关于它是如何工作的想法。
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
I developed the following directive which is working well under Chrome and IE11:
app.directive('whenRenderingDone', function($timeout, $parse){
return {
link: function (scope, el, attrs) {
var lastCount;
var lastTimer = 5000; // Initial timeout
//Check counter every few seconds, if no change since last time, this means rendering is done.
var checkRenderingDone = function (){
var mainPromiseResolved = scope.mainPromiseResolved;
lastCount = lastCount || -1;
if (lastCount === el.find('*').length && mainPromiseResolved) {
console.log('Rendering done, lastCount = %i', lastCount);
var func = $parse(attrs.whenRenderingDone);
func(scope);
} else {
lastCount = el.find('*').length;
console.log('mainPromiseResolved = %s, lastCount %i', mainPromiseResolved, lastCount)
console.log('Rendering not yet done. Check again after %i seconds.', lastTimer/1000.00);
stopCheckRendering = $timeout(checkRenderingDone, lastTimer);
lastTimer = lastTimer - 1000;
if (lastTimer <= 0) {
lastTimer = 1000;
}
return stopCheckRendering;
}
}
var stopCheckRendering;
stopCheckRendering = checkRenderingDone();
el.on('$destroy', function() {
if (stopCheckRendering) {
$timeout.cancel(stopCheckRendering);
}
});
}
}
});
I hope this will be of help to you, and if you have any comment to improve, please let me know. See this to give you an idea about how it is working.
Tarek
这篇关于如何检测在AngularJS中完成HTML渲染的时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!