AngularJS-需要$routeChangeStart和$locationChangeStart的一些组合
AngularJS - Need some combination of $routeChangeStart and $locationChangeStart
我的问题实际上与这里的问题非常相似:
AngularJs-取消路线更改事件
简而言之,我使用$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"answers"current"参数(请参阅AngularJS-$route)作为对象来检索我的"access"值。对于$locationChangeStart,这两个参数返回url字符串,而不是对象。因此,似乎没有办法检索我的"访问"值。
有没有什么方法可以将$locationChangeStart的重定向停止功能与$routeChangeStart的对象灵活性相结合,以实现我的需求?
想到的一种方法是尝试使用解析参数:
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' });
请注意,我还没有测试上面的代码,但我正在我的项目中做类似的事情。
我自己也面临同样的情况,我的解决方案与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版本以来,您实际上可以使用新引入的preventDefault方法。这样你就可以取消当前的路线更改,然后应用你自己的自定义重定向,如github问题所示:
$rootScope.$on("$routeChangeStart", function (event, next, current) {
if (next.access) {
event.preventDefault();
$rootScope.$evalAsync(function() {
$location.path('/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路由时,promise被拒绝(带有弹出窗口,可能是模式对话框),并且不遵循该路由。
希望这能帮助到别人。
- 组合框是否需要数据存储
- JavaScript - 需要帮助组合两个脚本
- 关于iframes.需要展示一个展示响应式设计的网站组合
- 需要构建文件组合上的 JS
- 组合框 ExtJs 的不需要的行为
- Jquery:需要检查组合框中的值列表
- 为什么在寄生组合继承中需要复制原型
- 需要在剑道网格内的组合框中进行验证
- 需要将两个数组合并为一个数组,以保持某个字符的位置
- AngularJS-需要$routeChangeStart和$locationChangeStart的一些组合
- 需要使用Knockout.js在组合框中保留动态创建的选项
- 我需要帮助组合或翻译c和JS
- 我需要更多的输入标签,而我的 HTML/JavaScript 组合不起作用
- 需要从多选选项组合值形成一个url与javascript
- 需要Lodash组合属性从数组中获取screenName
- 需要使用AJAX的多个组合框
- javascript加载器取代了脚本组合的需要
- 需要帮助理解递归函数以生成字符串的所有组合
- 在Extjs中,需要一个全局组合框类来处理不同json数据的不同实例
- 默认情况下,我需要在组合框中显示文本“选择一个”