Angular "navigate" 到 404 但保留 url
Angular "navigate" to 404 but keep url
我已经检查了很多问题和互联网,但没有任何运气,所以也许有人有类似的问题...
我实现了一个延迟加载模块:
{
component: LoginPageComponent,
path: '',
pathMatch: 'full'
},
{
canActivate: [AuthGuard],
loadChildren: () => import('./modules/home/home.module').then(m => m.HomeModule),
path: 'home'
},
在 HomeRoutingModule 中我还有一个
....
children: [
...
{
path: 'items',
canActivate: [SomeGuard,
loadChildren: () => ....
},
然后终于在那个子懒加载模块路由:
{
path: 'preview/:id',
canActivate: [ItemLoadedGuard],
component: PreviewPageComponent
},
所以某些条目的 URL 将是例如:/home/items/preview/some-random-id
。在那个 ItemLoaderGuard
中,我对该资源实施了 BE 调用,并在错误时导航到 404 页面。
但是当我通过这个实现时:
/home/items/preview/wrong-id
我将被重定向到 /404
页面。
我想做的是保留 url 并打开 404 页面组件,这样:
/home/items/preview/wrong-id
使用 NotFoundPageComponent 而不是 PreviewPageComponent
我试过使用导航附加功能,例如:skipLocationChange
和 replaceUrl
但没有效果。
除了在 PreviewPageComponent 中添加一些将显示未找到或未找到的包装器之外(下面的示例代码),还有其他方法可以解决这个问题吗?
<not-found *ngIf="displayNotFound"></not-found>
<div class="content" *ngIf="!displayNotFound">
....
</div>
我也在考虑将 url 存储在本地存储中,导航到 404 然后替换没有路径的 url,但也许有人有更好的解决方案?
将您的 preview.guard.ts 更改为
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({providedIn: 'root'})
export class PreviewGuard implements CanActivate {
constructor(private router: Router){}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if(next.params.id === '123-works'){
console.log('allowed')
return true;
} else {
console.log('not allowed');
setTimeout(() => this.router.navigateByUrl('404', {skipLocationChange: true}));
return true;
}
}
}
工作原理
其实当你引用的时候,你之前的url是主页而不是'wrong-id',当守卫发送false时,之前的url变成了主页并且return是错误的将您带到上一个 url。我在这里所做的是允许 url 被激活,因为我在 settimeout 中一直路由到 404,它将在导航到 'wrong-id'
后启动
我已经检查了很多问题和互联网,但没有任何运气,所以也许有人有类似的问题...
我实现了一个延迟加载模块:
{
component: LoginPageComponent,
path: '',
pathMatch: 'full'
},
{
canActivate: [AuthGuard],
loadChildren: () => import('./modules/home/home.module').then(m => m.HomeModule),
path: 'home'
},
在 HomeRoutingModule 中我还有一个
....
children: [
...
{
path: 'items',
canActivate: [SomeGuard,
loadChildren: () => ....
},
然后终于在那个子懒加载模块路由:
{
path: 'preview/:id',
canActivate: [ItemLoadedGuard],
component: PreviewPageComponent
},
所以某些条目的 URL 将是例如:/home/items/preview/some-random-id
。在那个 ItemLoaderGuard
中,我对该资源实施了 BE 调用,并在错误时导航到 404 页面。
但是当我通过这个实现时:
/home/items/preview/wrong-id
我将被重定向到 /404
页面。
我想做的是保留 url 并打开 404 页面组件,这样:
/home/items/preview/wrong-id
使用 NotFoundPageComponent 而不是 PreviewPageComponent
我试过使用导航附加功能,例如:skipLocationChange
和 replaceUrl
但没有效果。
除了在 PreviewPageComponent 中添加一些将显示未找到或未找到的包装器之外(下面的示例代码),还有其他方法可以解决这个问题吗?
<not-found *ngIf="displayNotFound"></not-found>
<div class="content" *ngIf="!displayNotFound">
....
</div>
我也在考虑将 url 存储在本地存储中,导航到 404 然后替换没有路径的 url,但也许有人有更好的解决方案?
将您的 preview.guard.ts 更改为
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({providedIn: 'root'})
export class PreviewGuard implements CanActivate {
constructor(private router: Router){}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if(next.params.id === '123-works'){
console.log('allowed')
return true;
} else {
console.log('not allowed');
setTimeout(() => this.router.navigateByUrl('404', {skipLocationChange: true}));
return true;
}
}
}
工作原理
其实当你引用的时候,你之前的url是主页而不是'wrong-id',当守卫发送false时,之前的url变成了主页并且return是错误的将您带到上一个 url。我在这里所做的是允许 url 被激活,因为我在 settimeout 中一直路由到 404,它将在导航到 'wrong-id'
后启动