In an AngularJS web application, a controller may require some data for initialization,
but this data needs to be retrieved from server. To meet this requirement, one solution is that after controller is initialized,
$http service to get the data and returns a
deferred. But this will change the usage of data to asynchronous operations,
which may not be possible for all scenarios. Developers usually prefer to synchronous operations. Another solution is to delay initialization of controller
until data is retrieved from server successfully.
To do this, we need to use a
run service to start retrieval of the data.
angular.module('services', ) .run(['$rootScope', 'dataService', ($rootScope, dataService) -> dataLoaded = false $rootScope.dataReady = false dataService.loadData().then(() -> dataLoaded = true ) $rootScope.$watch(() -> dataLoaded , (ready) -> $rootScope.dataReady = ready ) ])
After data is loaded,
$rootScope will be changed to
Then in controller,
angular.module('controllers', ['services']) .controller('MyCtrl', ['$scope', ($scope) -> $scope.$watch('dataReady', (ready) -> init() if ready ) init = () -> console.log('Init') ])
Controller watches change of
dataReady and start initialization after its value changed to
Source code is also available in GitHub Gist.
If this controller is used as a route, then
resolve property of
$routeProvider can be used.
angular.module('myModule', ) .config(['$routeProvider', 'dataService', ($routeProvider, dataService) -> $routeProvider .when('/path', templateUrl: 'tmpl.html' controller: 'MyController' resolve: data: () -> dataService.loadData() ])
ui-router also supports