在我的AngularJS应用程序中执行任何控制器之前,我需要加载一些全局数据(即在AngularJS中全局解析依赖关系)。
例如,我有一个具有getCurrentUser()
方法的UserService
,它向后端服务器发出请求,以获取有关当前已验证用户的数据。我有一个控制器,它需要这些数据来启动另一个请求(例如加载用户的余额)。
我怎样才能做到这一点呢?
发布于 2014-11-20 22:07:12
更新
如果可能,请考虑使用«Asynchronously Bootstrapping AngularJS Applications with Server-Side Data»文章中指定的方法。
您现在可以使用angular-deferred-bootstrap模块来实现这一点!
我不再确定这个答案的有效性,你仍然可以使用这些想法,但一定要用你的实际代码正确地测试它。我将努力使这个答案与never技术保持同步。
老答案
有几种方法可以解决异步应用程序初始化问题。
当涉及到在调用单个控制器之前必须解析的数据时-你可以很容易地使用ngRoute
的$routeProvider
的resolve
选项。但是,当你需要在调用任何控制器之前加载一些全局数据时-你必须即兴发挥。
我已经尝试在这个答案中收集所有可能的解决方案。我按优先顺序提供它们。
1.使用ui-router
当使用ui-router而不是原生ngRoute
时,您可以创建一个抽象根状态,并在激活子状态之前解析其中的所有数据。
我建议使用这种方法。ui-router
提供了许多附加功能,包括分层解决依赖关系的能力,并被开发人员社区很好地接受。
示例
module.config(function($urlRouterProvider, stateHelperProvider) {
$urlRouterProvider.otherwise('/404');
stateHelperProvider.setNestedState({
name: 'root',
template: '<ui-view/>',
abstract: true,
resolve: {
user: function(UserService) {
// getCurrentUser() returns promise that will be resolved
// by ui-router before nested states are activated.
return UserService.getCurrentUser();
}
},
children: [{
name: 'index',
url: '/',
templateUrl: '/partials/index'
}, {
name: 'not-found',
url: '/404',
templateUrl: '/partials/404'
}, {
name: 'balance',
url: '/balance',
templateUrl: '/partials/balance',
resolve: {
balance: function(UserService, user) {
// Using data resolved in parent state.
return UserService.getBalanceByAccountId(user.accountId);
}
}
}]
});
});
在使用抽象根作用域方法时,stateHelper
将极大地帮助减少代码。
根作用域被定义为抽象的,因此不能直接激活,并且它没有URL。
template: '<ui-view/>'
是正确呈现嵌套视图所必需的。
2.在根控制器中进行承诺
您可以做出承诺,并将它们添加到根控制器内部的函数中,即run()
函数。
我创建了一个Plunk来演示这个想法:http://plnkr.co/edit/gpguG5Y2S4KOz1KOKzXe?p=preview
这是一个完美的解决方案,然而,它膨胀了代码,使其更难使用和理解(回调地狱)。只有当第一种方法对你不起作用时,我才会推荐它。
3.通过应用程序页面传递数据
您可以将所有初始化数据直接包含到服务器上生成的HTML页面中,并从您的应用程序访问它。
考虑这个例子:
<html>
<body>
<script src="application.js"></script>
<script type="text/javascript">
application.init({
// Pass your data here.
userData: { ... }
});
</script>
</body>
</html>
您还可以在自定义application
对象的init()
方法中手动引导AngularJS应用程序。
我真的不喜欢这种方法,因为我确实认为Web应用程序的前端和后端应该高度分离。理想情况下,你的前端应该是一个静态网站(例如,可以通过CDN交付的一堆HTML、CSS和JS ),而你的后端应该是一个严格的API服务器,没有表示层(即它应该对HTML、CSS等一无所知)。但是,如果您能够忍受应用程序组件之间的紧密集成,那么这是一个可行的解决方案。
https://stackoverflow.com/questions/27050496
复制