Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS-需要一些$routeChangeStart和$locationChangeStart的组合_Javascript_Angularjs_Routes_Angularjs Directive_Angularjs Routing - Fatal编程技术网

Javascript AngularJS-需要一些$routeChangeStart和$locationChangeStart的组合

Javascript AngularJS-需要一些$routeChangeStart和$locationChangeStart的组合,javascript,angularjs,routes,angularjs-directive,angularjs-routing,Javascript,Angularjs,Routes,Angularjs Directive,Angularjs Routing,我的问题实际上与这里的问题非常相似: 简而言之,我使用$routeChangeStart并尝试使用$location更改当前路线。当我这样做时,控制台显示原始页面仍然被加载,并且很快被新页面覆盖 提供的解决方案是使用$locationChangeStart而不是$routeChangeStart,这应该可以防止额外的重定向。不幸的是,我在$routeprovider中使用了更改路由时需要访问的其他数据(我使用它跟踪页面限制)。这里有一个例子 $routeProvider. when('

我的问题实际上与这里的问题非常相似:

简而言之,我使用$routeChangeStart并尝试使用$location更改当前路线。当我这样做时,控制台显示原始页面仍然被加载,并且很快被新页面覆盖

提供的解决方案是使用$locationChangeStart而不是$routeChangeStart,这应该可以防止额外的重定向。不幸的是,我在$routeprovider中使用了更改路由时需要访问的其他数据(我使用它跟踪页面限制)。这里有一个例子

$routeProvider.
    when('/login', { controller: 'LoginCtrl', templateUrl: '/app/partial/login.html', access: false}).
    when('/home', { controller: 'HomeCtrl', templateUrl: '/app/partial/home.html', access: true}).
    otherwise({ redirectTo: '/login' });


$rootScope.$on('$routeChangeStart', function(event, next, current) {
    if(next.access){
        //Do Stuff
    }
    else{
        $location.path("/login");
        //This will load the current route first (ie: '/home'), and then
        //redirect the user to the correct 'login' route.
    }
});
使用$routeChangeStart,我可以使用“next”和“current”参数(请参阅)作为对象来检索我的“access”值。对于$locationChangeStart,这两个参数返回url字符串,而不是对象。因此,似乎没有办法检索我的“访问”值


有没有办法将$locationChangeStart的重定向停止功能与$routeChangeStart的对象灵活性结合起来,以实现我所需要的功能?

我想到的一种方法是尝试使用resolve参数:

var resolver = function(access) {
  return {
    load: function($q) {
      if (access) { // fire $routeChangeSuccess
        var deferred = $q.defer();
        deferred.resolve();
        return deferred.promise;
      } else { // fire $routeChangeError
        return $q.reject("/login");
      }
    }
  }
}

$routeProvider.
  when('/login', { controller: 'LoginCtrl', templateUrl: '/app/partial/login.html', resolve: resolver(false)}).
  when('/home', { controller: 'HomeCtrl', templateUrl: '/app/partial/home.html', resolve: resolver(true)}).
  otherwise({ redirectTo: '/login' });

请注意,我没有测试上面的代码,但我在我的项目中也做了类似的工作。

回答得好,马吕斯,让我走上正确的轨道。我在做这样的访问控制。然而,这是可行的

  var resolver = function(route, routeEvent) {
  return {
    load: function($q) {
      deferred = $q.defer();
      if (routeEvent!=3) { // eventually will be a list of routeEvents that the logged-in user is not allowed to visit read from a db table configured by admin
        deferred = $q.defer();
        deferred.resolve();
        return deferred.promise;
      } else { // fire $routeChangeError
        alert("You don't have permissions to access this.");
        deferred.reject(route);
        return deferred.promise;
      }
    }
  }
}

  var jsonRoutes = [

    {'route' : '/logout', 'templateUrl': 'partials/login.html',   'controller' : 'LoginCtrl', 'routeEvent' : 1 },
    {'route' : '/orders', 'templateUrl': 'partials/orders.html',   'controller': 'OrderListCtrl', 'routeEvent' : 2 },
    {'route' : '/products', 'templateUrl': 'partials/products.html',   'controller': 'ProductListCtrl', 'routeEvent' : 3 },

...

];


// somewhere on successful login code add in the dynamic routes

angular.forEach(jsonRoutes, function(r) {
                $route.routes[r.route] = {templateUrl: r.templateUrl, controller: r.controller, routeEvent: r.routeEvent, resolve: resolver(r.route, r.routeEvent)};
                  });


// got some static routes too which don't have access control - user has to login right?

  config(['$routeProvider', function($routeProvider) {


  $routeProvider.
    when('/error',  {templateUrl: 'partials/error.html',   controller : ErrorCtrl,  routeEvent : 1 }).
    when('/login',  {templateUrl: 'partials/login.html',   controller : LoginCtrl, routeEvent : 1 }).
    when('/home',  {templateUrl: 'partials/home.html',   controller : HomeCtrl, routeEvent : 1 }).
    when('/logout', {templateUrl: 'partials/login.html',   controller : LoginCtrl, routeEvent : 1 }).
    otherwise( {redirectTo: '/error'} );   
单击/orders路由时,承诺被拒绝(带有一个弹出窗口,可能是模态对话框),并且不遵循该路由


希望这对某人有所帮助。

我自己也面临同样的情况,我的解决方案与OP的意图一致

我使用
$locationChangeStart
事件和
$route
服务。通过访问
$route.routes
,我获得了使用
$routeProvider
定义的所有路由对象

.run(function($rootScope, $route, $location) {
  $rootScope.$on('$locationChangeStart', function(ev, next, current) {
    // We need the path component of `next`. We can either process `next` and 
    // spit out its path component, or simply use $location.path(). I go with
    // the latter.
    var nextPath = $location.path();
    var nextRoute = $route.routes[nextPath]

    console.log(nextRoute.access); // There you go!
  });
})
要从绝对URL解析路径组件,请执行以下操作:

var urlParsingNode = document.createElement('a');
urlParsingNode.href = next;  // say, next = 'http://www.abc.com/foo?name=joe
console.log(urlParsingNode.pathname)  // returns "/foo"

从1.3.0版开始,您实际上可以使用新引入的-方法。这样,您可以取消当前路线更改,然后应用自己的自定义重定向,如下所示:


我在自己的项目中实现了这个方法,效果非常好。希望它能帮助其他偶然发现它的人。

很抱歉回复太晚。当某件事对我起作用时,我会变得兴奋并继续前进。这最终成为了我所做工作的完美解决方案。在load函数中,我可以添加
$http
$location
之类的东西来进一步处理我的请求。我必须使我的load函数看起来更像Nick的函数(拒绝没有像这里写的那样工作)
load
函数应该读得更像这样:
var deferred=$q.deferred();if(access){deferred.resolve();}else{deferred.reject();$location.url('/login');}返回deferred.promise
@marius soutier对于
when()
resolve
选项非常巨大,如果url中有查询参数,该怎么办…如何识别正在使用的路由器called@niran-我已经为你更新了我的答案。看一看,这对带有参数的路由是如何工作的?比如/article/:articleId?@mkhatib-那会有点棘手。我注意到,
$route.routes
中的每个对象都有一个名为
regexp
的属性。顾名思义,它是一个正则表达式对象,您可以使用它与解析完整URL(如上所述)时得到的路径组件进行匹配,同时循环通过
$route.routes
。我从未尝试过,但我认为应该可以。为了将包含参数的任意路径与参数化路由RegExp进行匹配,您必须检查
路由
对象的某些子集(如果不是全部的话)。例如,如果路径的第一个组件在任何路由中都不是参数,则可以将其缩小。不过,迭代对象以检查多个RegExp似乎效率低下,尤其是对于
$locationChangeStart
进程。

$rootScope.$on("$routeChangeStart", function (event, next, current) {
    if (next.access) {
      event.preventDefault();
      $rootScope.$evalAsync(function() {
        $location.path('/login');
      });
    }
});