2015-07-12 25 views
1

在Laravel中,设置路由过滤器非常简单。我们使用beforeFilter([])并指定控制器中的哪些功能应在身份验证时可访问,并且在特殊情况下也有except如何在ui.router状态设置路由过滤器?

现在,我刚开始使用Angular的ui.router和国家的概念当然是前进的方式,但我在这里问一个noob问题。如何在我的状态上设置路由过滤器。我绝对不想在个人路线上使用resolve

这是一些代码。这是我用于我的个人资料路线。我使用resolve以确保它只在通过身份验证时才可访问。但问题是,当我登录时,我的登录和注册路线仍然可以访问,他们不应该这样做。它应该只是重定向到家。

现在我可以将解析状态添加到我不想在登录时访问的状态,但方式是否正确?如果有很多,会怎么样。这将是重复的代码。有没有'ui.router`的方式来做到这一点?

.state('profile', { 
       url: '/profile', 
       templateUrl: 'js/app/partials/profile.html', 
       controller: 'ProfileCtrl', 
       resolve: { 
        authenticated: function($q, $location, $auth) { 
         var deferred = $q.defer(); 

         if (!$auth.isAuthenticated()) { 
          $location.path('/login'); 
         } else { 
          deferred.resolve(); 
         } 

         return deferred.promise; 
        } 
       } 
      }) 
+0

你为什么不听像'$ stateChangeStart'事件和你想在这里做像'认证是什么'。 –

+0

你能举一个@ K.Toress的例子吗? –

回答

2

我想一个办法是创建请问您的验证,然后在运行块,你会调用该服务上的任何$stateChangeStart事件K.Toress提到的服务。

如果您想指定哪些状态需要验证,例如,您可以在状态定义配置中使用数据选项来定义它是否需要验证。因此,要在被传递一个toState参数,从中可以访问data性质的$stateChangeStart事件定义需要身份验证,你可以尝试像的状态......

$stateProvider 
    .state('foo', { 

    templateUrl: 'foo.html', 

    // etc... 

    data: { 
     requiresAuth: true 
    } 

    }); 

然后,您可以检查。

var app = angular.module('foo', ['ui.router']) 

.factory('RouteValidator', ['$rootScope', '$auth', function($rootScope){ 

    return { 
    init: init 
    }; 

    function init(){ 
     $rootScope.$on('$stateChangeStart', _onStateChangeStart); 
    } 

    function _onStateChangeStart(event, toState, toParams, fromState, fromParams){ 


    // check the data property (if there is one) defined on your state 
    // object using the toState param 

    var toStateRequiresAuth = _requiresAuth(toState), 

     // if user is not authenticated and the state he is trying to access 
     // requires auth then redirect to login page 

     if(!$auth.isAuthenticated() && toStateRequiresAuth){ 
      event.preventDefault(); 
      $state.go('login'); 
      return; 
     } 

    } 

    function _requiresAuth(toState){ 
     if(angular.isUndefined(toState.data) || !toState.data.requiresAuth){ 
      return false; 
     } 
     return toState.data.requiresAuth; 
    } 

}]) 

.run(['RouteValidator', function(RouteValidator){ 
    // inject service here and call init() 
    // this is so that you keep your run blocks clean 
    // and because it's easier to test the logic in a service than in a 
    // run block 
    RouteValidator.init(); 
}]); 

编辑

好吧,我做了一个非常基本的DEMO上plunker,希望能展示的概念。我也会在这里发布代码。帮助这个帮助。

app.js

var app = angular.module('plunker', ['ui.router']); 

app.config(['$stateProvider', function($stateProvider){ 

    $stateProvider 

    .state('public', { 
     url: "/public", 
     templateUrl: "public.html" 
    }) 

    .state('login', { 
     url: "/login", 
     templateUrl: "login.html", 
     controller: function($scope) { 
     $scope.items = ["A", "List", "Of", "Items"]; 
     } 
    }) 

    .state('admin', { 

     url: "/admin", 
     templateUrl: "admin.html", 

     data: { 
     requiresAuth: true 
     }, 

     controller: function($scope) { 
     $scope.items = ["A", "List", "Of", "Items"]; 
     } 

    }); 

}]); 

app.factory('User', [function(){ 
    return { 
    isAuthenticated: false 
    }; 
}]); 

app.factory('RouteValidator', ['$rootScope', 'User', '$state', function($rootScope, User, $state){ 

    return { 
    init: init 
    }; 
    ///////////////////////////////// 

    function init(){ 
     $rootScope.$on('$stateChangeStart', _onStateChangeStart); 
    } 

    function _onStateChangeStart(event, toState, toParams, fromState, fromParams){ 

    var toStateRequiresAuth = _requiresAuth(toState); 

    if(!User.isAuthenticated && toStateRequiresAuth){ 
     event.preventDefault(); 
     $state.go('public'); 
     alert('You are not authorised to see this view'); 

     return; 
    } 

    } 

    function _requiresAuth(toState){ 
     if(angular.isUndefined(toState.data) || !toState.data.requiresAuth){ 
      return false; 
     } 
     return toState.data.requiresAuth; 
    } 

}]); 

app.run(['RouteValidator', function(RouteValidator){ 
    RouteValidator.init(); 
}]); 

app.controller('MainCtrl', function($scope) { 
    $scope.name = 'World'; 
}); 

的index.html

<!DOCTYPE html> 
<html ng-app="plunker"> 

    <head> 
    <meta charset="utf-8" /> 
    <title>AngularJS Plunker</title> 
    <script>document.write('<base href="' + document.location + '" />');</script> 
    <link rel="stylesheet" href="style.css" /> 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.4.2/angular.js" data-semver="1.4.2"></script> 
    <script data-require="[email protected]" data-semver="0.2.15" src="//rawgit.com/angular-ui/ui-router/0.2.15/release/angular-ui-router.js"></script> 
    <script src="app.js"></script> 
    </head> 

    <body ng-controller="MainCtrl"> 

    <a ui-sref="public">public</a> 
    <a ui-sref="login">login</a> 
    <a ui-sref="admin">admin</a> 
    <div ui-view></div> 

    </body> 

</html> 
+0

感谢您的回答。有没有这样的内置ui路由器? –

+0

据我所知不是。 ui.router只是给你'$ stateChangeStart'事件,你可以使用它来实现你想要的。 –

+0

啊,这太遗憾了。你可以给我一个完整的例子来帮助我开始踢球。理想情况下,我希望提供一组我希望通过身份验证的状态以及一系列未经身份验证的状态,以便在登录后访问登录页面和注册页面时,您只需返回主页。 –