我是AngularJS和ui-router的初学者,我试图在未找到的资源上处理404。我想显示一个错误,而不改变地址栏中的URL。
我已经这样配置了我的状态:
app.config([
"$stateProvider", function($stateProvider) {
$stateProvider
.state("home", {
url: "/",
templateUrl: "app/views/home/home.html"
})
.state("listings", {
abstract: true,
url: "/listings",
templateUrl: "app/views/listings/listings.html"
})
.state("listings.list", {
url: "",
templateUrl: "app/views/listings/listings.list.html",
})
.state("listings.details", {
url: "/{id:.{36}}",
templateUrl: "app/views/listings/listings.details.html",
resolve: {
listing: [
"$stateParams", "listingRepository",
function($stateParams, repository) {
return repository.get({ id: $stateParams.id }).$promise;
}
]
}
})
.state("listings.notFound", {
url: "/404",
template: "Listing not found"
});
}
]);
(我实际上使用TypeScript,但我试图改变以上是纯JavaScript)
如果,比如说,我导航到以下url:http://localhost:12345/listings/bef8a5dc-0f9e-4541-8446-4ebb10882045
这将打开listing .details状态。但是,如果该资源不存在,则resolve函数返回的承诺将失败并返回404,我在这里捕获:
app.run([
"$rootScope", "$state",
function($rootScope, $state) {
$rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) {
event.preventDefault();
if (error.status === 404) {
$state.go("^.notFound", null, { location: true, relative: toState });
}
});
}
]);
我现在要做的是找到列表。notFound状态,而不改变地址栏中的目的URL。我使用一个相对路径,因为我想在其他资源中重用这个逻辑。
然而,我得到一个异常:"^路径。not found ' not valid for state 'listings.details'
这个错误的发生是因为$stateChangeError事件给出的toState参数不知道它的父变量,即toState。父级未定义。在ui-router的transitionTo函数中,我看到作为参数给出的对象是to.self
,它只提供了信息的一个子集。使用relative: $state.get(toState.name)
也没有帮助,因为内部ui-router再次返回state.self
我希望避免维护一个绝对路径列表,并重写在状态层次结构中导航的逻辑(无论它有多简单,DRY等等)。
我做错了吗,还有其他正确的方法处理404吗?如果没有,最好的方法是什么?
最好使用$urlRouterProvider
来处理这些异常
app.config([
"$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/404');
// define states
}]);