Angularjs 在使用routeProvider启动Angular中的路由之前,如何检查登录或其他状态?

Angularjs 在使用routeProvider启动Angular中的路由之前,如何检查登录或其他状态?,angularjs,angular-routing,Angularjs,Angular Routing,假设我有4条路由-2条需要用户登录,2条不需要。我的应用程序初始化看起来像: $routeProvider.when('/open1',{templateUrl:'/open1.html',controller:'Open1'}); $routeProvider.when('/open2',{templateUrl:'/open2.html',controller:'Open2'}); $routeProvider.when('/secure1',

假设我有4条路由-2条需要用户登录,2条不需要。我的应用程序初始化看起来像:

        $routeProvider.when('/open1',{templateUrl:'/open1.html',controller:'Open1'});
        $routeProvider.when('/open2',{templateUrl:'/open2.html',controller:'Open2'});
        $routeProvider.when('/secure1',{templateUrl:'/secure1.html',controller:'Secure1'});
        $routeProvider.when('/secure2',{templateUrl:'/secure2.html',controller:'Secure2'});
路由
/open1
/open2
对所有人开放,而路由
/secure1
/secure2
要求用户登录,如果没有,则采取一些措施,例如重定向到登录或发出警告。我可以通过使用我的
Auth
服务和调用来确定用户的状态,例如
Auth.isLogin()
。因此,结果将是:

  • 转到
    /open1
    /open2
    始终转到上面声明的模板和控制器
  • 如果
    Auth.isLogin()
    返回true,
    /secure1
    /secure2
    转到上述声明的模板和控制器
  • 如果
    Auth.isLogin()
    返回false,
    /secure1
    /secure2
    执行一些其他操作,例如
    $location.path('/login')
我可以将逻辑放在检查的
Secure1
Secure2
控制器中,但这是重复的,混淆了责任,使它们更难测试,等等

是否有一种方法可以使用
$routeProvider
声明“检查此路由和此路由,如果没有,则重定向”?我曾考虑以某种方式使用
resolve
,但不太确定如何使用它(关于
resolve
的文档不是很清楚,并且很少有有用的示例)

编辑:

根据下面的答案,似乎有三种方法可以做到这一点:

  • 使用
    resolve
    检查登录并使承诺失败,然后捕获要重定向的
    $routeChangeError
    事件
  • 仅使用
    $routeChangeStart
    事件检查登录并重定向
  • 使用just resolve检查登录并重定向

第二个选项是两位回答者的建议。

我也有同样的问题,我是这样做的:

var app = angular.module('myModule',["ui-bootstrap"]);
然后在应用程序中侦听位置更改(这也将触发页面的OneNoter)

我希望这有帮助

使用指令处理AngularJS中的用户身份验证

$route服务在路由更改之前发出$routeChangeStart

如果不使用指令,可以通过调用app.run来捕获该事件(可以将其放在定义路由的代码[app.config]之后)。例如:

为了充分披露,我使用ui.router,这是我在应用程序中使用的改编代码

var app = angular.module('app');

app.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/open1',{templateUrl:'/open1.html',controller:'Open1'});
    $routeProvider.when('/open2',{templateUrl:'/open2.html',controller:'Open2'});
    $routeProvider.when('/secure1',{templateUrl:'/secure1.html',controller:'Secure1'});
    $routeProvider.when('/secure2',{templateUrl:'/secure2.html',controller:'Secure2'});
}]);

app.run(['$rootScope', '$location', 'Auth', function($rootScope, $location, Auth) {
    $rootScope.$on('$routeChangeStart', function(event, currRoute, prevRoute){
        var logged = Auth.isLogin();

        //check if the user is going to the login page
        // i use ui.route so not exactly sure about this one but you get the picture
        var appTo = currRoute.path.indexOf('/secure') !== -1;

        if(appTo && !logged) {
            event.preventDefault();
            $location.path('/login');
        }
    });
}]);

在我上面的评论中,有3种不同的路径(如果您想从html模板中控制指令,还可以使用指令)。我最后跟在后面

其实质是:

$routeProvider.when('/secure', {
    templateUrl: '/secure.html', 
    controller: 'Secure',
    resolve:{
        loggedIn:onlyLoggedIn
    }
 });
然后
onlyLoggedIn

var onlyLoggedIn = function ($location,$q,Auth) {
    var deferred = $q.defer();
    if (Auth.isLogin()) {
        deferred.resolve();
    } else {
        deferred.reject();
        $location.url('/login');
    }
    return deferred.promise;
};

简单,就像一种魅力。如果我需要一个指令,我会将此部分拉入服务。

这不是一个坏计划,但我需要在事件处理程序中为每个路由添加逻辑,如何停止特定路由的运行?我添加了“抛出”停止执行“;”这将停止所有javascript活动。并重定向到登录页面。在函数中,我检查$location.path==“/signin”;我想这会管用的。
$routeProvider
中是否没有可以帮助的内容?没有,$routeProvider中没有用于身份验证的内容,您可以随时查看一个外部模块,就像我使用resolve跟踪一样。这是最简单的。所以我可以使用
$routeChangeStart
事件捕获并阻止继续?我仍然需要知道路径,如果可以的话,我更愿意在
$routeProvider.when()
中这样做,但这会起作用。这与下面的@JasonvanderZeeuw答案类似。我会看这篇博文的,谢谢you@deitch我会推荐,因为它使用状态而不是URL。例如,状态可以是secure.report或secure.list,而url可以是/report或/list,那么您只需检查状态名称中是否包含secure,而不知道博客感兴趣的确切链接。他建议在模板上设置一个指令,而不是在路线上这样做。我不确定我是否喜欢这种方法,我想我更喜欢在路线(或州)层面上,但这个想法可能会奏效。我会试试的。你能告诉我把var onlyLoggedIn放在哪里吗,比如在哪个范围内?我对它很陌生@deitch@AayushKumarSingha我只是在app.js中将它声明为局部变量函数,然后在我的
$routeProvider
中引用它。但它可以是你想要的任何地方,因为你总是可以<代码>要求()/代码>或其他方式包括它。你的URL是DealURL不再死掉,我得到它:)它又死了,所以让我们走一个回程机:
var onlyLoggedIn = function ($location,$q,Auth) {
    var deferred = $q.defer();
    if (Auth.isLogin()) {
        deferred.resolve();
    } else {
        deferred.reject();
        $location.url('/login');
    }
    return deferred.promise;
};