没有内置的方法来设置路由约束,但您可以使用解析功能自己轻松完成。
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
and name
into PostCtrl
:
module.controller('PostCtrl', function ($scope, $routeParams, id, name) {
});
id
在这种情况下将是一个数字。你当然也可以使用$routeParams.id
and $routeParams.name
但那些总是字符串。
如果传递的不是数字,则承诺将被拒绝,您需要处理该问题,如果您正在进行 SPA,通常在“MainCtrl”或“AppCtrl”中处理。
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
});
});
Update
您可以将解析与$routeChangeError
事件来验证路线并在错误时重定向。解析属性始终会运行,即使它们没有注入到控制器中。
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
并在需要时中止。否则这个问题本来可以解决得更好。