【发布时间】:2014-07-21 10:08:50
【问题描述】:
我是 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)
如果我导航到以下网址:
http://localhost:12345/listings/bef8a5dc-0f9e-4541-8446-4ebb10882045
这应该会打开 Listings.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 });
}
});
}
]);
我在这里要做的是转到 listings.notFound 状态,而不更改地址栏中的目标 URL。 我使用相对路径是因为我想将此逻辑重新用于其他资源。
但是,我得到了一个例外:
路径“^.notFound”对于状态“listings.details”无效
发生此错误是因为 $stateChangeError 事件给出的 toState 参数不知道其父级,即 toState.parent 未定义。
在ui-router的transitionTo函数中,我可以看到作为参数给出的对象是to.self,它只提供了信息的一个子集。
使用 relative: $state.get(toState.name) 也无济于事,因为内部 ui-router 再次返回 state.self
我想避免维护绝对路径列表,并重写在状态层次结构中导航的逻辑(不管它多么简单,DRY 等等)。
我是不是搞错了,还有另一种处理 404 的正确方法吗? 如果不是,最好的方法是什么?
【问题讨论】:
-
你解决过这个问题吗?我遇到了非常相似的事情并且被卡住了:(
标签: javascript angularjs angular-ui-router