Angular 阻止 URL 导航但保留按钮导航
Angular prevent URL navigation but keep button navigation
我目前正试图阻止用户浏览 url 本身。用户应该只能使用按钮进行导航。
基本上我的路由是这样的:
const routes: Routes = [
{ path: 'form', component: FormComponent},
{ path: '', redirectTo: '/form', pathMatch: 'full' },
{ path: 'attachment', component: AttachmentComponent },
{ path: 'inbox', component: InboxComponent},
{ path: 'summary', component: SummaryComponent },
{ path: 'answer/:id', component: SummaryComponent}
];
所以基本上用户应该能够使用 url 本身导航到“/form”和 "answer/:id" 但所有其他路由如 attachment/inbox/summary 应该只能通过按钮访问(例如,用户继续 /form 并有一个指向附件和摘要的按钮,或者用户继续“/answer:id”并带有一个指向收件箱的按钮)。
我尝试的第一件事是在路由模块中设置以下参数(不设置守卫):
@NgModule({
imports: [RouterModule.forRoot(routes, { initialNavigation: false })],
exports: [RouterModule]
})
不可能通过 url 导航(这很好)并且可以使用按钮导航,但遗憾的是我无法打开我的 "form" 或 "answer" 路线,这是必要的.
我试过设置守卫 :
const routes: Routes = [
{ path: 'form', component: FormComponent},
{ path: '', redirectTo: '/form', pathMatch: 'full' },
{ path: 'attachment', component: AttachmentComponent , canActivate:[DirectAccessGuard]},
{ path: 'inbox', component: InboxComponent, canActivate: [DirectAccessGuard]},
{ path: 'summary', component: SummaryComponent, canActivate: [DirectAccessGuard]},
{ path: 'answer/:id', component: SummaryComponent}
];
后卫:
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router} from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DirectAccessGuard implements CanActivate {
constructor(private router: Router) { }
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
// If the previous URL was blank, then the user is directly accessing this page
return false;
}
}
使用 url 打开 "form" 和 "answer" 是可能的,但无法使用按钮重定向到另一个组件。有道理,因为我总是返回错误。
所以我的问题是:是否有可能在我的守卫中获得目标 url?
如果我在 /form 上并且我想重定向到 /attachment 我知道我可以使用 this.router.url
获得“/form”但我想要目标 url(在这种情况下为“/attachment”)。
或者有没有其他方法可以解决我的问题?
是的,可以从 ActivatedRouteSnapshot 中获取目标 url in guard。
ActivatedRouteSnapshot 中的 routeConfig 属性 有一个路径 属性 给目标 url.
我已经按照上述场景进行了测试,
现在路线如下所示,
const routes: Routes = [
{ path: 'form', component: FormComponent },
{ path: '', redirectTo: '/form', pathMatch: 'full' },
{ path: 'attachment', component: AttachmentComponent, canActivate: [DirectAccessGaurd] },
{ path: 'inbox', component: InboxComponent, canActivate: [DirectAccessGaurd] },
{ path: 'summary', component: SummaryComponent, canActivate: [DirectAccessGaurd] },
{ path: 'answer/:id', component: SummaryComponent, canActivate: [DirectAccessGaurd] },
{ path: '**', component: NotfoundComponent }
]
所以,实际逻辑在 Gaurd 中,
import { Injectable } from '@angular/core';
import { CanActivate, RouterStateSnapshot, ActivatedRouteSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DirectAccessGaurd implements CanActivate {
constructor(private router: Router) { }
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if(this.router.url === '/form') {
if(next.routeConfig.path === 'attachment' || next.routeConfig.path === 'inbox') {
return true;
}
}
if(next.routeConfig.path === 'answer/:id') {
return true; // To allow answer/:id route through url
}
if(this.router.url.startsWith('/answer/')) {
if(next.routeConfig.path === 'summary') {
return true;
}
}
this.router.navigate(['/notfound'])
return false;
}
}
逻辑很简单,
首先我检查当前 url 是否为 '/form',然后检查目标 url 是附件还是收件箱,然后我分别重定向到那些。
我目前正试图阻止用户浏览 url 本身。用户应该只能使用按钮进行导航。
基本上我的路由是这样的:
const routes: Routes = [
{ path: 'form', component: FormComponent},
{ path: '', redirectTo: '/form', pathMatch: 'full' },
{ path: 'attachment', component: AttachmentComponent },
{ path: 'inbox', component: InboxComponent},
{ path: 'summary', component: SummaryComponent },
{ path: 'answer/:id', component: SummaryComponent}
];
所以基本上用户应该能够使用 url 本身导航到“/form”和 "answer/:id" 但所有其他路由如 attachment/inbox/summary 应该只能通过按钮访问(例如,用户继续 /form 并有一个指向附件和摘要的按钮,或者用户继续“/answer:id”并带有一个指向收件箱的按钮)。
我尝试的第一件事是在路由模块中设置以下参数(不设置守卫):
@NgModule({
imports: [RouterModule.forRoot(routes, { initialNavigation: false })],
exports: [RouterModule]
})
不可能通过 url 导航(这很好)并且可以使用按钮导航,但遗憾的是我无法打开我的 "form" 或 "answer" 路线,这是必要的.
我试过设置守卫 :
const routes: Routes = [
{ path: 'form', component: FormComponent},
{ path: '', redirectTo: '/form', pathMatch: 'full' },
{ path: 'attachment', component: AttachmentComponent , canActivate:[DirectAccessGuard]},
{ path: 'inbox', component: InboxComponent, canActivate: [DirectAccessGuard]},
{ path: 'summary', component: SummaryComponent, canActivate: [DirectAccessGuard]},
{ path: 'answer/:id', component: SummaryComponent}
];
后卫:
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router} from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DirectAccessGuard implements CanActivate {
constructor(private router: Router) { }
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
// If the previous URL was blank, then the user is directly accessing this page
return false;
}
}
使用 url 打开 "form" 和 "answer" 是可能的,但无法使用按钮重定向到另一个组件。有道理,因为我总是返回错误。
所以我的问题是:是否有可能在我的守卫中获得目标 url?
如果我在 /form 上并且我想重定向到 /attachment 我知道我可以使用 this.router.url
获得“/form”但我想要目标 url(在这种情况下为“/attachment”)。
或者有没有其他方法可以解决我的问题?
是的,可以从 ActivatedRouteSnapshot 中获取目标 url in guard。 ActivatedRouteSnapshot 中的 routeConfig 属性 有一个路径 属性 给目标 url.
我已经按照上述场景进行了测试, 现在路线如下所示,
const routes: Routes = [
{ path: 'form', component: FormComponent },
{ path: '', redirectTo: '/form', pathMatch: 'full' },
{ path: 'attachment', component: AttachmentComponent, canActivate: [DirectAccessGaurd] },
{ path: 'inbox', component: InboxComponent, canActivate: [DirectAccessGaurd] },
{ path: 'summary', component: SummaryComponent, canActivate: [DirectAccessGaurd] },
{ path: 'answer/:id', component: SummaryComponent, canActivate: [DirectAccessGaurd] },
{ path: '**', component: NotfoundComponent }
]
所以,实际逻辑在 Gaurd 中,
import { Injectable } from '@angular/core';
import { CanActivate, RouterStateSnapshot, ActivatedRouteSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class DirectAccessGaurd implements CanActivate {
constructor(private router: Router) { }
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if(this.router.url === '/form') {
if(next.routeConfig.path === 'attachment' || next.routeConfig.path === 'inbox') {
return true;
}
}
if(next.routeConfig.path === 'answer/:id') {
return true; // To allow answer/:id route through url
}
if(this.router.url.startsWith('/answer/')) {
if(next.routeConfig.path === 'summary') {
return true;
}
}
this.router.navigate(['/notfound'])
return false;
}
}
逻辑很简单, 首先我检查当前 url 是否为 '/form',然后检查目标 url 是附件还是收件箱,然后我分别重定向到那些。