otherwise() 部分捕获与任何指定路由都不匹配的路径。
在您的情况下,路由匹配,但模板在指定的 URL 上不可用。
$routeProvider 对此一无所知,也无能为力。
您可以做的是以某种方式(见下文)检查模板是否可用,如果不可用,请使用$location 重定向到适当的路径(例如/error/404)。
为了确定页面是否有效(即其模板可用),您可以尝试访问模板(使用$http)并捕获任何错误(表明没有模板)等。但我没有像这种方法(因为依靠模板的可用性来确定页面的存在/有效性并不是一个很好的实践imo - 例如,在网络或服务器问题等情况下,它很容易导致误导性错误消息)。
我最喜欢的方法是保留“有效”/现有页面的列表并对其进行检查。如果当前页面应该可用,则照常继续获取模板等。如果没有,则重定向到错误页面。
上面描述的逻辑可以放在$routeProvider的resolve属性中(所以它在控制器被实例化和视图加载之前被执行)。
例如:
var app = angular.module(...);
// This should be a constant, so it can
// get injected into configuration blocks
app.constant('EXISTING_PAGES', [
'page1',
'page2',
...
]);
app.config(function configRouteProvider($routeProvider, EXISTING_PAGES) {
$routeProvider.
when('/', {
templateUrl: 'views/dashboard.html'
}).
when('/:page', {
templateUrl: function getPageTemplateUrl(routeParams) {
return 'views/' + routeParams.page + '.html';
},
resolve: {
exists: function resolveExists($location, $route) {
// Because this is executed before the instantiation of the
// controller and the view is not fully loaded yet, the parameters
// should be accessed via `$route.current.params`
if (EXISTING_PAGES.indexOf($route.current.params.page) === -1) {
// This is not a valid/existing page,
// let's redirect to an appropriate error page
$location.replace(); // Replace the URL in the history
$location.path('/error/404');
}
return true;
}
}
}).
// This should be a separate route, so we can redirect to it
when('/error/404', {
templateUrl: '404.html'
}).
otherwise({
redirectTo: '/error/404'
});
});
另请参阅此short demo。