我来自Asp.net MVC世界,路线限制非常有用。我目前正在开发一个包含客户端路由的Angular JS SPA。
我还想在我的客户端路由中添加参数约束,如:
$.routeProvider.when("/post/:id/:name?")
我希望将:id
参数限制为只有在这些数字时才有效。
我没有在Angular Docs中找到类似的东西(至少可以说是可怕的)。可以吗?也许还有参数默认值?
答案 0 :(得分:10)
没有内置的方法来设置路由约束,但是你可以通过使用解析功能轻松地完成它。
module.config(function ($routeProvider) {
$routeProvider.when('/post/:id/:name', {
controller: 'PostCtrl',
resolve: {
id: function ($q, $route) {
var deferred = $q.defer(),
id = parseInt($route.current.params.id, 10);
if (!isNaN(id)) {
deferred.resolve(id);
} else {
deferred.reject('Id is not a number');
}
return deferred.promise;
},
// This isn't really needed, you can extract the name using
// $routeParams.name as you usually would in the controller.
name: function ($route) {
return $route.current.params.name;
}
}
});
});
通过这种方式,您可以将id
和name
注入PostCtrl
:
module.controller('PostCtrl', function ($scope, $routeParams, id, name) {
});
在这种情况下, id
将是一个数字。您当然也可以使用$routeParams.id
和$routeParams.name
,但这些始终是字符串。
如果传递了除数字之外的其他内容,则承诺将被拒绝,您需要处理该承诺,通常在“MainCtrl”或“AppCtrl”中进行处理(如果您正在进行SPA)。
module.controller('AppCtrl', function ($scope, $log) {
$scope.$on('$routeChangeError', function (ev, current, previous, rejection) {
$log.error('Error changing route: ' + rejection);
// Will print: Error changing route: Id is not a number
});
});
<强>更新强>
您可以将resolve与$routeChangeError
事件结合使用来验证路由并在出错时重定向。即使它们未在控制器中注入,也始终运行resolve属性。
resolve: {
validation: function ($q, $route) {
var deferred = $q.defer(),
id = parseInt($route.current.params.id, 10);
if (!isNaN(id)) {
deferred.resolve();
} else {
deferred.reject('VALIDATION FAILED');
}
return deferred.promise;
}
}
在您的家庭控制器中,只需添加:
module.controller('AppCtrl', function ($scope, $location) {
$scope.$on('$routeChangeError', function (ev, current, previous, rejection) {
if (rejection === 'VALIDATION FAILED') {
$location.path('/home');
}
});
});
这是解决它的一种非常黑客的方式,你可能更好地使用ui-router(我没有尝试过那个)。不幸的是,如果需要,不可能听$routeChangeStart
并中止。否则,这可以解决得更好。
答案 1 :(得分:5)
有一个pull request in AngularJS source(由我制作),它为路由参数添加正则表达式约束。它提供这种路由定义很简单:
/:parameter:regularexpression
一个例子是
/profile/:id:[1-9]\\d*/edit
这意味着id
必须是一个不以0开头的数字。
这些参数当然有一些额外的要求:
参数不能是可选的或贪婪的 - 如果它以?
或*
结尾,则此字符将成为正则表达式的一部分(因为它们都是具有各自含义的正则表达式标记
正则表达式约束不能使用正则表达式捕获组作为(
和)
作为正则表达式约束的一部分进行转义 - 这已经以这种方式工作,因此如果您的参数名称包含{ {1}}或(
他们都将被转义
正则表达式约束不能包含)
,因为它们是路径段分隔符
答案 2 :(得分:2)
一种方法是使用ui-router,它允许使用正则表达式指定网址。