我的模块有一个依赖于$rootScope.foo
的控制器,该控制器由$http
服务填充。 我的问题是如何确保在加载控制器之前填充$rootScope.foo
。
我尝试在模块的$rootScope.foo
方法中加载run()
:
myModule.run(function($rootScope, $http, $location) {
$http.get("http://mydomain/load_user/").
success(function(respData) {
$rootScope.foo = respData.foo;
});
});
但它不起作用,因为控制器在success()
内的代码之前加载。
答案 0 :(得分:9)
使用promises实现$http
服务。
您在success
处理程序中编写的代码将在解析承诺时运行。由于承诺的异步性质,不知道何时发生这种情况。它可以是1秒后或10秒后。
与此同时,您的其他代码会继续运行,并且您的控制器可能会在承诺解决之前加载。
解决这个问题的最好方法是用“异步”术语思考,而不是强迫某种同步行为。
以下是一些有效选项:
您可以将代码移动到控制器并将逻辑移动到成功处理程序,如下所示:
myModule.controller('SomeCtrl', function($rootScope, $http, $location) {
$http.get("http://mydomain/load_user/").
success(function(respData) {
// Perform any logic you need here and use respData.foo;
});
});
另一种方法是使用事件通知您的控制器何时解析了承诺(并且数据已从服务器加载),如下所示:
myModule.run(function($rootScope, $http, $location) {
$http.get("http://mydomain/load_user/").
success(function(respData) {
$rootScope.foo = respData.foo;
// Broadcast event that foo was updated
$rootScope.$broadcast('fooWasUpdated');
});
});
然后在您的控制器中,您可以为事件添加一个监听器:
myModule.controller('SomeCtrl', function($scope, $rootScope) {
$scope.$on('fooWasUpdated', function(event){
// Perform your logic with $rootScope.foo
});
});
第三种方法是根本不使用$rootScope
,而是使用事件来通知听众并使用如下事件传递数据:
myModule.run(function($rootScope, $http, $location) {
$http.get("http://mydomain/load_user/").
success(function(respData) {
// Broadcast event that foo was updated
// You can add data as extra arguments
$rootScope.$broadcast('fooWasUpdated', respData.foo);
});
});
然后在您的控制器中,您可以为事件添加一个监听器:
myModule.controller('SomeCtrl', function($scope, $rootScope) {
$scope.$on('fooWasUpdated', function(event, foo){
// Perform your logic with foo instead of $rootScope.foo
});
});
您可以在AngularJS documentation for scopes中找到有关$broadcast
和$on
的详细信息。
使用事件的一些好处是:
希望有所帮助!