简体   繁体   中英

Angular: Reload $rootscope user before initializing controller

I'm working on a SPA with AngularJS. After the sign in, a cookie is created with a token and a user object is stored in $rootScope.user which is conveniently accessible from various controllers as they are dynamically loaded.

The application works fine when I use it normally and navigate around.

When I refresh a page with F5, angular is reloaded and the module run() method checks if the cookie exists and reloads the user from the server into $rootScope.user . However, while this is happening, another controller is already expecting $rootScope.user to have a user.

How can I prevent controller initialization before my $rootScope.user is ready and loaded. If can, of course, check in the controller if there is a user loaded in $rootScope . But if there isn't, how can $rootScope invoke a controller to carry out some initialization?

Here is code in app.run():

app.run(function ($rootScope, $location, $cookies, appServices) {

    var token = $cookies.get('UserToken');
    if (token) $rootScope.token = token;

    $rootScope.$on("$routeChangeStart", function (event, next, current) {

        // Get user from server if token is there but no user
        if ($rootScope.user == null) {
            if ($rootScope.token) {
                appServices.getUserByToken(token).then(function (d) {
                    if (d.Code == 1) {
                        $rootScope.user = d.ReturnObj;
                        if ($rootScope.user != null && next.templateUrl == "web/views/signin.html") $location.path("/dashboard");
                    } else $rootScope.goSignin(next.templateUrl);
                });
            }
            else $rootScope.goSignin(next.templateUrl);
        }
    });
})

And here is sample code in a controller that is dynamically loaded:

app.registerCtrl('userdetailCtrl', function userdetailCtrl($scope, $http, $rootScope, $routeParams, appServices, $location, validationService) {

  $scope.getOffices=function()
    {
      appServices.getOffices({ ID: $rootScope.user.OrgID, Token: $rootScope.token }).then(function (d){
      if(d.Code==1){$scope.office = d.ReturnObj;}});
    }

  $scope.getOffices();

});

The getOffices() function requires $rootScope.user.OrgID , which is not found as $rootScope.user is not yet loaded.

Any ideas?

Not sure if this will work in your situation, but

$rootScope.$on('$includeContentLoaded', function () {
    //fetch user here
}

solved a similar issue that I had

You can do several things, here's an example of two of these. Check the console in this fiddle

1. Watch the variable for changes:

The first is watching $rootScope.user for changes in your controller:

App.run:

$timeout(function() {
    $rootScope.user = 'user';
}, 500)

in your controller:

$rootScope.$watch('user', function(newVal, oldVal) {
   console.log(newVal, $rootScope.user); 
});

You can 'unwatch', too, if you don't want to keep executing code every time the user variable changes.

2. Emitting an event

The second is emitting an event, and catching it where required, like this:

App.run:

$timeout(function() {
    $rootScope.user = 'user';
    $rootScope.$broadcast('userEvent');
}, 500)

Your controller:

$rootScope.$on('userEvent', function() {
    console.log($rootScope.user);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM