我已经对该主题进行了广泛的研究,但是无论我做什么,我都很难实现这一目标。
当所有元素都已在AngularJS Web应用程序中完全呈现后,我想执行代码。我想我找到了建议使用路由器和视图的解决方案,但由于它似乎需要某些配置,因此无法在我的情况下进行。
当您有ng-repeat和大量嵌套的directives时,它们会根据不同的条件使用ng-if生成HTML /内容,我注意到即使在触发文档就绪事件或加载了视图内容后,HTML渲染仍会继续,即< x3>事件被触发。
我最接近的想法是在给定directive元素的子元素的整个长度上使用$watch。每次执行$watch时,递增计数器renderCount。然后,在另一个计时器事件中,检查计数器renderCount在过去的3-5秒内是否没有变化,那么我们可以假设渲染已完成。
监视孩子并检查是否不再进行渲染的代码如下:
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);
}
}
});
我将尝试实施上述方法,如果您有任何反馈意见,请告诉我。
塔雷克
我开发了以下指令,该指令在Chrome和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);
}
});
}
}
});
希望对您有所帮助,如果您有任何意见需要改进,请告诉我。 看到此内容可让您了解其工作方式。
塔雷克
摘要循环完成后,可以使用$$postDigest运行代码。 您可以在此处阅读有关范围生命周期的更多信息
// Some $apply action here or simply entering the digest cycle
scope.$apply(function () { ... });
...
scope.$$postDigest(function () {
// Run any code in here that will run after all the watches complete
// in the digest cycle. Which means it runs once after all the
// watches manipulate the DOM and before the browser renders
});
谢谢! 我会尝试的。 但是,我记得任何以$$开头的AngularJS API都不是100%安全使用的,对吗?
抱歉,您的解决方案对我不起作用。 请参阅上面的我的解决方案,以便您对我正在尝试做的事情有更好的了解。 谢谢!