使用异步数据进行角度应用初始化

时间:2015-08-18 18:14:13

标签: angularjs angular-ui-router

我需要使用整个应用所依赖的一些用户数据来初始化我的Angular。因此,我需要在路由器启动并初始化控制器之前解析初始化。

目前,我在角度模块的run()块中编写了初始化代码。初始化涉及获取用户数据的异步http请求,而应用程序的其余部分依赖于用户数据。 在路由器启动控制器初始化之前,如何确保解析http请求?

我正在使用ui-router。

初始化包括以下内容: 1)获取cookie'userId' 2)从服务器获取用户(异步http请求,整个应用程序取决于用户) 3)设置authService.currentUser

这是代码的示例

.run(['$cookies', 'userApiService', 'authService', 
  function($cookies, userApiService, authService){

    var userId = $cookies.get('userId');
    userId = parseCookieValue(userId);

    userApiService.getOne(userId).then(function(user){
      authService.currentUser = user;
    });
}])
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', 
  function($stateProvider, $urlRouterProvider, $locationProvider) {

    $locationProvider.html5Mode(true);

    $urlRouterProvider.when('/', '/main');

    $stateProvider
      .state('login', {
        url: '/login',
        views: {
          'header': {
            templateUrl: 'views/header.html',
            controller: 'HeaderCtrl'
          },
          'content': {
            templateUrl: 'views/login.html',
            controller: 'LoginCtrl'
          },
          'footer': {
            templateUrl: 'views/footer.html',
          }
        }
      })
      .state('main', {
        url: '/main',
        views: {
          'content@': {
            template: '',
            controller: function($state, authService) {
              if(!authService.isAuthenticated()) {
                $state.go('login');
              }
              if(authService.isStudent()) {
                $state.go('student');
              }
              if(authService.isAdmin()) {
                $state.go('admin');
              }
            }
          }
        }
      })
      .state('student', {
        url: '/student',
        views: {
          'header@': {
            templateUrl: 'views/header.html',
            controller: 'HeaderCtrl'
          },
          'content@': {
            templateUrl: 'views/student.html',
            controller: 'StudentCtrl'
          },
          'footer@': {
            templateUrl: 'views/footer.html',
          }
        }
      })
      .state('admin', {
        url: '/admin',
        views: {
          'header@': {
            templateUrl: 'views/header.html',
            controller: 'HeaderCtrl'
          },
          'content@': {
            templateUrl: 'views/admin.html',
            controller: 'AdminCtrl'
          },
          'footer@': {
            templateUrl: 'views/footer.html',
          }
        }
      })
}])

1 个答案:

答案 0 :(得分:2)

扩展某人的评论,您可以创建一个root状态,该状态是您所有其他应用的状态(来自根目录的孩子)的父级。 root状态解析所有用户数据,然后您可以将用户数据注入任何控制器或将其存储在服务中。

$stateProvider
  .state('root', {
    url: '',
    abstract: true,
    template: '',     // some template with header, content, footer ui-views
    resolve: {
      // fetch user data
    }
  })
  .state('root.login', {
    url: '/login',
    views: {
      'header': {
        templateUrl: 'views/header.html',
        controller: 'HeaderCtrl'
      },
      'content': {
        templateUrl: 'views/login.html',
        controller: 'LoginCtrl'
      },
      'footer': {
        templateUrl: 'views/footer.html',
      }
    }
  })
  .state('root.main', {
    url: '/main',
    views: {
      'content@': {
        template: '',
        controller: function($state, authService) {
          if(!authService.isAuthenticated()) {
            $state.go('login');
          }
          if(authService.isStudent()) {
            $state.go('student');
          }
          if(authService.isAdmin()) {
            $state.go('admin');
          }
        }
      }
    }
  })

  ...  // your other states

关键是您的所有应用状态必须是您的root州的孩子,即您的州声明中的root.<name>。这将确保在您的用户数据可用之前不会启动其他控制器。有关resolve以及如何使用read here的更多信息。另外,parent and child states