Angular ui-router:如何在授权完成之前推迟呈现模板?

时间:2014-07-05 03:32:41

标签: angularjs angular-ui-router

我的ui-router配置如下:

$stateProvider
  .state('app', {
    url: '/app',
    abstract: true,
    templateUrl: 'sidemenu/sidemenu.html',
    controller: 'SideMenuCtrl'
  })
  .state('login', {
    url: '/login',
    templateUrl: 'login/login.html',
    controller: 'LoginCtrl'
  })
  .state('app.dashboard', {
    url: '/dashboard', 
    views: {
      menuContent: {
        templateUrl: 'dashboard/dashboard.html',
        controller: 'DashboardCtrl'
      }
    }
  })
  [More states here]

$urlRouterProvider.otherwise('/app/dashboard');

当用户导航到/app/dashboard时,我想检查他们是否已获得授权,然后:

  • 如果未经授权,则重定向到/login,或
  • 如果获得授权,则允许查看信息中心

这似乎可以解决问题:(基于this example

$rootScope.$on('$stateChangeSuccess', function(event) {
  var path = $location.path();

  if (path === '/login') {
    return;
  }

  // Halt state change from even starting
  event.preventDefault();

  Auth.getCurrentUser().then(function(currentUser) {
    if (currentUser === null) {
      $state.go('login');
    } else {
      // Continue with the update and state transition
      $urlRouter.sync();
    }
  });
});

此解决方案的唯一问题是,如果未授权用户导航到信息中心,首先显示信息中心模板。只有在授权响应返回时,它才会更改为登录模板。

在我们授权用户时,有没有办法不显示信息中心?

我还尝试将$stateChangeSuccess更改为$stateChangeStart,但它确实没有用(路由似乎完全被破坏了)。

2 个答案:

答案 0 :(得分:8)

使用解析块怎么样?

.state('app.dashboard', {
    url: '/dashboard', 
    views: {
        menuContent: {
            templateUrl: 'dashboard/dashboard.html',
            controller: 'DashboardCtrl',
            resolve: {
                login: function($q, Auth) {
                    var deferred = $q.defer();
                    Auth.getCurrentUser().then(function(currentUser) {
                        if (currentUser == null) {
                            deferred.reject();
                        } else {
                            deferred.resolve();
                        }
                    });
                    return deferred.promise;
                }
            }
        }
    }
})

状态变化不会发生,直到承诺得到解决,因此模板不应该显示。拒绝承诺将根据this answer引发$stateChangeError,因此您需要处理该错误并重定向到登录页面。

答案 1 :(得分:0)

您可以在路由上使用resolve并在用户未登录时拒绝承诺,因此永远不会到达控制器。