Angular 指令:如何确保所有嵌套模板和部分加载? [英] Angular directive: how to make sure all nested templates and partials loaded?

查看:20
本文介绍了Angular 指令:如何确保所有嵌套模板和部分加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设,我正在制作一个自定义的 Angular 指令,它必须检查和操作其中的 DOM 树(准确地说:应用指令的元素下的 DOM 树).这种操作的正确位置是指令的后链接函数.

Suppose, I am making a custom Angular directive that has to examine and manipulate the DOM tree inside it (to be precise: the DOM tree under the element the directive is applied to). The right place for such manipulation is the directive's post-link function.

当指令中的所有 HTML 都被内联时,这很好用.当在指令内部我们有其他指令使用templateUrl"属性加载模板时会出现问题,或者仅使用ng-include"指令来插入部分.

That works fine while all the HTML inside the directive is inlined. Problems appear when inside the directive we have other directives that load their templates using "templateUrl" property, or just "ng-include" directives to insert partials.

那些模板和部分是异步加载的.这意味着,在编译阶段 Angular 将启动部分加载并继续编译而不等待加载完成.然后,在链接父指令的那一刻,包含的部分加载可能仍在进行中,因此指令的 post-link 函数在内部看不到任何内容.

Those templates and partials are loaded asynchronously. That means, at the compile stage Angular will initiate the partial loading and will continue compiling without waiting for the loading to complete. Then, at the moment the parent directive is linked, the contained partials loading may still be in progress, so the directive's post-link function sees nothing inside.

换句话说:指令的 post-link 函数被设计为在它被调用时准备好所有嵌套的 DOM,但对于异步模板和包含,情况并非如此!

In other words: the directive's post-link function is designed to have all nested DOM ready by the moment it is called, but with the async templates and includes this is not the case!

模板预加载也无济于事,因为它们仍然是异步访问的.

And template pre-loading does not help, because they are still accessed asynchronously.

人们如何克服这一点?

这个任务似乎很常见,但我没有设法找到一个好的和可靠的解决方案.我是否错过了一些明显的东西?...

The task seems to be quite common, but I did not manage to find a good and reliable solution. Do I miss something obvious?...

更新:我已经创建了一个 Plunk说明问题.实际上,它仅重现了 ng-include 的问题,子指令作品的外部模板.在我的项目中它没有,也许这是一个竞争条件,我必须进行更多调查.

Update: Well I have created a Plunk to illustrate the problem. Actually it reproduces only the problem with ng-include, the external template for sub-directive works. In my project it did not though, maybe this is a race condition, I have to investigate more.

推荐答案

你可以等待主视图的加载:

You can wait for the load of the main view with:

$scope.$on('$viewContentLoaded', function () {
  //Here your view content is fully loaded !!
});

这个技巧和 $timeout 一样,如果你用 ng-include 加载视图就不起作用.您应该等待所有部分视图.正确的事件顺序是:

This trick, same as $timeout, not works if you are loading views with ng-include. You should wait for all the partial views. The right events order is:

  1. $viewContentLoaded
  2. $includeContentRequested
  3. $超时
  4. $includeContentLoaded

您可以使用 $includeContentRequested$includeContentLoaded 和一个计数器来等待所有包含的部分内容:

You can use $includeContentRequested and $includeContentLoaded with a counter for wait the content of all included partials:

var nIncludes = 0;
$scope.$on('$includeContentRequested', function (event, templateName) {
  nIncludes++;
  console.log(nIncludes, '$includeContentRequested', templateName);
});

$scope.$on("$includeContentLoaded", function (event, templateName) {          
   nIncludes--;
   console.log(nIncludes, '$includeContentLoaded', templateName);
   if (nIncludes === 0) {
     console.log('everything is loaded!!');
     // Do stuff here
   }            
}); 

我还没有找到其他更优雅的解决方案.

I have not found another more elegant solution.

这篇关于Angular 指令:如何确保所有嵌套模板和部分加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆