简体   繁体   English

延迟角度控制器直到Ajax调用完成

[英]Deferring angular controllers until Ajax call is completed

First of all, I have googled and searched on SO for this question. 首先,我用Google搜索并搜索了这个问题。 None of the answers I've seen are really satisfactory for me. 我见过的所有答案都不能让我满意。 I am aware of resolve & manually bootstrapping angular and neither are great solutions for us. 我知道解决方案和手动启动角度,对我们来说都不是很好的解决方案。

Essentially our app is constructed such that at the top level, we have a 基本上我们的应用程序是这样构建的,在顶层,我们有一个

<body ng-controller="applicationController">

that instantiates a bunch of stuff. 实例化一堆东西。 Part of that is getting some data from our server and setting it so that children controllers have access to it. 部分原因是从我们的服务器获取一些数据并进行设置,以便子控制器可以访问它。 So the issue is sometimes the children controllers are executed before the server has responded. 因此,问题有时是在服务器响应之前执行子控制器。

We use angular UI's ui-router so we can take advantage of states. 我们使用角度UI的ui-router,这样我们就可以利用状态。 However resolve hasn't been a great solution for us because we have a bunch of routes and a user can enter the app from any of them. 然而,对于我们来说,解决方案并不是一个很好的解决方案,因为我们有一堆路由,用户可以从任何一个进入应用程序。 So far my only solutions are to create a very high level parent state and putting a resolve on that, or putting a resolve a multitude of states. 到目前为止,我唯一的解决方案是创建一个非常高级的父状态并对此做出决心,或者解决多个状态。 Is there a way to make the ajax call before the angular controllers are run? 有没有办法在角度控制器运行之前进行ajax调用?

What about ng-include ( http://docs.angularjs.org/api/ng.directive:ngInclude )? ng-include( http://docs.angularjs.org/api/ng.directive:ngInclude )怎么样? Remove all the subcontroller stuff from your html file and put it in a template file. 从html文件中删除所有子控制器内容并将其放在模板文件中。 Now you may load some data from your server and if they all have arrived set the ng-include src. 现在您可以从服务器加载一些数据,如果它们都已到达,则设置ng-include src。

With this solution you also have the possibility showing another template file during the loading phase. 使用此解决方案,您还可以在加载阶段显示另一个模板文件。

If you don't want your content in another file you may consider writing a directive that can handle inline templates: 如果您不希望将内容放在另一个文件中,您可以考虑编写一个可以处理内联模板的指令:

<script type="text/ng-template" id="my-awesome-content.html">
   ... 
</script>

If you want to delay the instantiation of your controller, you need at some point to take advantage of promises and $routeProvider . 如果你想延迟控制器的实例化,你需要在某些时候利用promises$routeProvider

Misko Hevery (the creator of AngularJS) answered such question here: Delaying AngularJS route change until model loaded to prevent flicker Misko Hevery (AngularJS的创建者)在这里回答了这样的问题: 延迟AngularJS路线改变直到模型加载以防止闪烁

He updated the "AngularJS getting started tutorial" to conform to that pattern; 他更新了“AngularJS入门教程”以符合该模式; it is worth reading it. 值得一读。

I run into the same question a few months ago; 几个月前我遇到了同样的问题; I architected my app to follow that principle. 我构建了我的应用程序以遵循该原则。

Basically set a url/entry point in your app that resolves the instantiation of your controllers. 基本上在应用程序中设置一个url /入口点,用于解析控制器的实例化。

If your app is accessible from other locations, redirect the call to that entry point/url; 如果您的应用可以从其他位置访问,请将呼叫重定向到该入口点/网址; after the init stuff has been resolved, redirect to the requested url. 解析初始化后,重定向到请求的URL。

I upvoted both answers here because, in my opinion, the most elegant solution is a combination of both (without redirecting back and forth). 我在这里赞成了两个答案,因为在我看来,最优雅的解决方案是两者的结合(没有来回重定向)。 The core of this problem is the fact that angular only allows synchronised dependency injection on controller arguments via the route provider. 这个问题的核心是angular只允许通过路由提供程序对控制器参数进行同步依赖注入。 We can however wrap all our initialisation in a single service and let our main controller to be dependent on this. 然而,我们可以将所有初始化包装在一个服务中,让我们的主控制器依赖于此。

See this plunker for a live demo. 查看此plunker进行现场演示。

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

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