繁体   English   中英

在 Angular 加载完所有视图后运行 Javascript

[英]Run Javascript AFTER Angular Has Finished Loading All Views

我正在使用 Angular 构建一个 Web 应用程序,我试图找到一种方法来等待所有data-ng-include元素都已评估并且包含完成加载。 例如,菜单是一个加载的视图,每个页面的主要内容也是如此,因此至少有两个data-ng-include被评估和加载。 最重要的是,菜单 include 嵌套了data-ng-repeat来构建我的菜单。 我需要一种在所有这些包含和其中的任何角度函数都已加载并且 DOM 实际准备就绪后启动脚本的方法。

当 Angular 完成页面设置时,是否有任何事件被触发?

AnguarJS 的实现是基本的,我们基本上通过使用 data-ng-include 将其用于模板化。 每个页面都是一个视图(不是角度视图,只是一个 html 文件),通过 data-ng-include 加载,页眉和页脚在其上方和下方。 标头还动态加载包含 angular.html 的全局视图(同样不是角度视图)html 文件。

到目前为止,除了模板之外,菜单是唯一使用 AngularJS 的东西。 它使用它使用 JSP 动态生成并插入到从服务器返回的 DOM 中的 JSON 对象来创建菜单。

为了让前端人员的工作更轻松,任何类型的重复 JavaScript 功能都被编码到模块中,这些模块在页面加载时被检测到,并使用需要附加 JavaScript 功能的元素上的 data-features 属性动态加载到。

例如,您可能有<div id="mySubMenu" data-features="subMenu"></div> 在页面加载时,会检测每个带有 data-features 元素的元素,并加载关联的 JS 模块,在这种情况下,我们将加载/scripts/modules/subMenu.js

我需要的是一种延迟运行此功能检测和附件的方法,直到包含或其他角度函数产生的所有元素都在页面上并准备好进行操作,特别是因为其中可能存在具有数据特征属性的元素包括。

其他地方有人提到在身体上放一个控制器,但什么都不放:

$scope.$on('$viewContentLoaded', function() {
    // Init Features Here
});

那没有用,所以我在这里寻找其他选择。

我最终在这个问题中使用了 Theo 的解决方案: 当 angular.js 完成加载时发送事件

在加载的内容上:

$rootScope.$on('$includeContentLoaded', function() {
    //do your will
});

关于请求的内容:

$rootScope.$on('$includeContentRequested', function() {
    //...
});

我确信这不是正确的方法,但是......

将下面的函数放在我的视图控制器中,在视图加载到我的应用程序中后运行该函数。 我相信该函数会在视图加载后的下一个摘要循环中运行(如果错误,请在此处纠正我),因此它会在页面形成后运行。

setTimeout(function(){
  //do this after view has loaded :)
  console.log('success!');
}, 0);

在每个视图 setTimeouts 返回后,您可以通过回调将它们链接在一起和/或使用异步并行库来执行另一个函数。

我认为合适的答案是否定的。 您必须改变查看应用程序和模型的方式,并使其适应“角度方式”。 很可能有一种更健康的方式来实现您的需求。 如果您需要将事件附加到元素,您可能想要使用指令,但当然我没有足够的信息在这个阶段判断什么是最好的。

angular.module 和指令是一个很好的探索选择。

这是一个关于如何将两者与 JQUERY 插件一起使用的 plunker 演示:

http://plnkr.co/edit/WGdNEM?p=preview

这是一个在单独文件上带有指令的示例:

http://plnkr.co/edit/YNBSWPLeWqsfGvOTwsMB?p=preview

您可以使用 JQuery Promise,并在您的 Angular 根控制器中实现此承诺。 在 angular 控制器或 jquery 代码运行之前设置承诺:

var AppReadyDeferred = $.Deferred();
var AppReadyPromise = AppReadyDeferred.promise();

一旦一切准备就绪,在你的角度控制器里面,做

AppReadyDeferred.resolve();

在你的 jQuery 代码中等待它被解决

window.AppReadyPromise.done(() => {
  // Angular is ready to go!;
});

使用 ng-cloak 在编译之前延迟显示模板。 您还可以向具有 ng-cloak 的 html 元素添加一个隐藏字段作为最后一个子元素(最好在 body 标签或 ng-app 开始的任何地方使用它),然后您可以检查此隐藏元素是否存在间隔循环

您的隐藏字段部分将是这样的

<div ng-include="'ngtplhidden'"></hidden>
<script type="text/ng-template" id="ngtplhidden">
<span id="elemidToCheckInAnIntervalFunc"></span>
</script>

您可以尝试使用document.onreadystatechange

document.onreadystatechange = x => {
    console.log('ready!');
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM