在我的index.html文件中,我得到一个appController
,就像main controller
一样,必须在$ rootScope中加载一些基本设置,以便我可以在child controllers
中使用这些设置(data-ui-view = ui-router插件)。
<body ng-controller="appController">
<div data-ui-view></div>
</body>
在appController
我使用服务(appService),我从数据库中获取数据并将一小部分数据放入$ rootScope属性formData
appService.formData()
.then(function(data) {
$rootScope.formData = data[0].num;
if ($rootScope.formData) {
$rootScope.$broadcast('afterFormDataLoaded');
}
})
在$ rootScope.formData填充实际数据之前,其他(子)控制器不运行非常重要。所以为了实现这一点,我在父控制器中使用$rootScope.$broadcast
并且:
$scope.$on('afterFormDataLoaded', function () {
// the code
})
子控制器中的 $scope.$on
。
这个有效!我的子控制器仅在主控制器中的$broadcast
设置为afterFormDataLoaded
后才会运行。
但是当我改变视图并且从一个孩子(视图和控制器)导航到另一个孩子时,我遇到了问题。
对我来说很明显我会遇到$broadcast
方法的问题,因为当我加载/刷新页面而不是当我更改视图时,$ broadcast会运行一次。因此,当我更改视图时,不会触发$scope.$on
。
让我的所有子控制器等到我的父异步功能成功完成并且$ rootScope.formData是 true 的正确和最合理的方法是什么?
答案 0 :(得分:1)
在ui-router中,您可以将resolve参数添加到状态声明(https://github.com/angular-ui/ui-router/wiki#resolve)。为了使它工作,你必须存储承诺的某个地方直到解决。
这里是一个例子
angular.run(['$rootScope', '$q', function($rootScope, $q){
var defer = $q.defer();
var dataPromise = defer.promise;
$rootScope.resolveDataPromise = function(data){
defer.resolve(data);
}
}]);
angular.config(['$stateProvider', function($stateProvider){
$stateProvider.state({
resolve:{
myData:['$rootScope', function($rootScope){
return $rootScope.dataPromise;
}]
}
});
}]);
appService.formData().then(function(data) {
if(data[0].num){
$rootScope.resolveDataPromise(data[0].num);
}
})
注意:要获取解析数据,只需将其注入控制器,解析对象的关键字就是名称: myData 。
你可以在你需要的所有状态下定义它,也可以在所有状态的父级中定义它,这将有效。
答案 1 :(得分:0)
你可以在相应的控制器上引用$ rootScope,如果$ rootScope.formData被填充,则在start函数中读取,如果没有注册你的监听器。
此外,如果您使用的是ui-router
resolve,可能会完全按照您的意愿行事。