Reputation: 1290
In my index.html file i got a appController
that is like a main controller
that has to load some basic settings in the $rootScope so i can use these settings in the child controllers
(data-ui-view = ui-router plugin).
<body ng-controller="appController">
<div data-ui-view></div>
</body>
In the appController
i'm using a service (appService) where i get data from the database and put a fraction of that data in a $rootScope property formData
appService.formData()
.then(function(data) {
$rootScope.formData = data[0].num;
if ($rootScope.formData) {
$rootScope.$broadcast('afterFormDataLoaded');
}
})
It's very important that other (child) controllers don't run before the $rootScope.formData is filled with the actual data. So to accomplish that i use $rootScope.$broadcast
in the parent controller and:
$scope.$on('afterFormDataLoaded', function () {
// the code
})
$scope.$on
in the child controllers.
This works! My child controller is only running after the $broadcast
in the main controller is set to afterFormDataLoaded
.
But i'm having problems when i change the view and i navigate from one child (view & controller) to another.
It's clear for me that i will have problems with that $broadcast
method because $broadcast run one time when i load/refresh the page and not when i change the view. So $scope.$on
will not be triggered when i change the view.
what is the proper and most plausibly way to let all my child controllers wait until my parent asynchronous function is succesfully done and $rootScope.formData is true?
Upvotes: 1
Views: 503
Reputation: 5353
In ui-router you can add a resolve parameter to state declaration (https://github.com/angular-ui/ui-router/wiki#resolve). In order to have it working you have to store somewhere the promise until is resolved.
Here's is an example
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);
}
})
Note : to get the data of the resolve you can just inject it in your controller, the key of the resolve object will be the name : myData here.
You can either define it in all state you need it or in a parent of all the state, this will work.
Upvotes: 1