我需要在AngularJS应用程序中执行任何控制器之前加载一些全局数据(即在AngularJS中全局解析依赖关系)。
例如,我有一个UserService
,其getCurrentUser()
方法向后端服务器发出请求,以获取有关当前已验证用户的数据。我有一个控制器需要这些数据才能启动另一个请求(例如加载用户的余额)。
我怎样才能做到这一点?
答案 0 :(得分:22)
如果可能,请考虑使用«Asynchronously Bootstrapping AngularJS Applications with Server-Side Data»文章中指定的方法。
您现在可以使用angular-deferred-bootstrap模块实现这一目标!
我不再确定此答案的有效性,您仍然可以使用这些想法,但请务必使用您的实际代码对其进行正确测试。我会尝试将这个答案保持最新,而不是技术。
有几种解决异步应用程序初始化问题的方法。
说到在调用单个控制器之前必须解决的数据 - 您可以轻松使用resolve
ngRoute
的{{1}}选项。但是,当您需要在调用任何控制器之前加载某些全局数据时 - 您必须即兴发挥。
我试图在这个答案中收集所有可能的解决方案。我按优先顺序提供它们。
使用ui-router而不是本地$routeProvider
时,您可以在激活子状态之前创建抽象根状态并解析其中的所有数据。
我建议使用这种方法。 ngRoute
提供了许多其他功能,包括以层次结构方式解析依赖关系的功能,并且被开发人员社区广泛接受。
ui-router
使用抽象根范围方法时,stateHelper
将极大地减少代码。
根作用域定义为摘要,因此无法直接激活且没有URL。
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);
}
}
}]
});
});
是嵌套视图正确呈现所必需的。
您可以制作承诺并将其添加到根控制器内的template: '<ui-view/>'
,即$rootScope
功能。
我创建了一个Plunk来演示这个想法: http://plnkr.co/edit/gpguG5Y2S4KOz1KOKzXe?p=preview
这是一个完美的解决方案,然而,它使代码膨胀并使其更难以使用和理解(回调地狱)。只有当第一种方法不适合你时,我才会推荐它。
您可以将所有初始化数据直接包含在服务器上生成的HTML页面中,并从您的应用程序访问它。
考虑这个例子:
run()
您可以在自定义<html>
<body>
<script src="application.js"></script>
<script type="text/javascript">
application.init({
// Pass your data here.
userData: { ... }
});
</script>
</body>
</html>
对象的init()
方法中手动引导AngularJS应用程序。
我真的不喜欢这种方法,因为我确实认为Web应用程序的前端和后端应该高度分离。理想情况下,您的前端应该是一个静态网站(例如,可以通过CDN提供的一堆HTML,CSS和JS),您的后端应该是一个没有表示层的严格的API服务器(即它应该对HTML,CSS和这样)。但是,如果您能够在应用程序组件之间实现紧密集成,那么它就是一个可行的解决方案。