如果设置了位置,如何在每个状态检查 router-ui,如果没有则转到登录页面?

How to check in router-ui on each state if location is set, if not then go to landing page?

如何在angular路由器-ui中实现以下场景:除了登录页面用户无法浏览没有位置的页面。无论用户是否登录,如果设置了位置,请检查每个状态更改,如果没有,则转到登录页面。如果用户已登录并有一个位置,则设置一个 cookie,如果没有,则转到登录页面。

我目前的想法,但是行不通,是否完全正确?

var app = angular.module('myApp', ['ngCookies', 'ui.router', 'Devise', 'ngResource']);

app.config([
    '$stateProvider', '$urlRouterProvider' '$cookies', function ($stateProvider, $urlRouterProvider, $cookies) {
    $stateProvider.state('home', {
        url: '/home',
        templateUrl: 'home/_home.html',
        controller: 'MainCtrl'
    }).state('landing', {
        url: '/landing',
        templateUrl: 'landing.html',
        controller: 'landing',
        resolve: {
            location: [
                '$state ', '$stateParams', '$q', '$window', '$cookies', function ($state, $stateParams, $q, $window, $cookies) {
                  var deferred = $q.defer();

                 $window.navigator.geolocation.getCurrentPosition(function (position) {
                    $cookies.location = position;
                    deferred.resolve(position);
                 });
                 return deferred.promise;

            }]
        }
    }).state('login', {
        url: '/login ',
        templateUrl: 'auth/_login.html ',
        controller: 'AuthCtrl',
        onEnter: [
            '$state', 'CustomAuth', function ($state, CustomAuth, $cookies) {
            CustomAuth.currentUserResource().then(function (resp) {
              $cookies.location = resp.data.user.location;
              $state.go('home');
            });
        }]
    })
    $urlRouterProvider.otherwise('home');
}]);

app.run(function($rootScope, $cookies) {
  $rootScope.$on('$stateChangeStart', function(event, toState) {
    if (!$cookies.location) {
      event.preventDefault();
      $state.go('landing');
    }
  });
});

a working example。我们必须做一些调整。

首先,我们需要正确设置监听器。它不能重定向,当已经 recireted

app.run(['$rootScope', '$state', '$cookies',
  function($rootScope, $state, $cookies) { 
  $cookies.location = "";

  $rootScope.$on('$stateChangeStart', function(event, toState) {

    if(toState.name ===  "landing")
    {
      // already was redirected 
      // we head to landing
      // get out of hee
      return; 
    } 

    if ($cookies.location === "") 
    {

      event.preventDefault();
      $state.go('landing'); 
    }
  });

}]);

此外,$cookies 不是提供者,而是服务。这意味着,我们不能在 .config() 阶段使用它,而只能在 .run() 阶段使用它。

这意味着,它可以注入到 .run() 方法、controller() 或其他一些服务中,但不能注入到 .config()

调整了定义,修复了许多小问题:

.config(['$stateProvider', '$urlRouterProvider',
    function ($stateProvider, $urlRouterProvider) {
    $stateProvider.state('home', {
        url: '/home',
        templateUrl: 'tpl.html',
        controller: 'MainCtrl'
    })
    .state('landing', {
        url: '/landing',
        templateUrl: 'tpl.html',
        controller: 'landing',
        resolve: {
            location: [
                '$state', '$stateParams', '$q', '$window', '$cookies'
                , function ($state, $stateParams, $q, $window, $cookies) {
                  var deferred = $q.defer();

                  // example how to quickly set some value
                  $cookies.location = "some position";
                  deferred.resolve($cookies.location);                    

                 return deferred.promise;    
            }]
        }
    })
    .state('login', {
        url: '/login ',
        templateUrl: 'tpl.html',
        controller: 'AuthCtrl',
        ...
    })
    $urlRouterProvider.otherwise('home');
}])

勾选working example here