角度阻止URL导航,但保持按钮导航

时间:2019-07-12 09:08:30

标签: angular routing

我目前正在尝试阻止用户浏览网址本身。用户应该只能使用按钮进行导航。

基本上,我的路由如下:

    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}
];  

因此,基本上,用户应该可以使用网址本身导航到“ / form”和“ answer /:id”,但所有其他路由(如附件/收件箱/摘要)都只能通过按钮访问(例如,用户继续/ form并有一个指向附件和摘要的按钮,或者用户使用带有指向收件箱的按钮继续“ / answer:id”。

我尝试的第一件事是在路由模块中设置以下参数(不设置防护):

@NgModule({
  imports: [RouterModule.forRoot(routes, { initialNavigation: false })],
  exports: [RouterModule]
})

无法通过url导航(这很好),并且可以使用可用的按钮进行导航,但是很遗憾,我无法打开必要的“表单”或“答案”路线。
我尝试设置一名警卫:

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打开“表单”和“答案”,但是使用按钮重定向到另一个组件无效。有道理,因为我总是返回false。
所以我的问题是:是否可以在我的守护程序中获取目标网址?
如果即时消息位于/ form上,并且我想重定向到/ attachment,我知道我可以使用this.router.url来获得“ / form”,但是我想要目标网址(在这种情况下为“ / attachment”)。 还是有其他方法可以解决我的问题?

1 个答案:

答案 0 :(得分:0)

是的,可以从 ActivatedRouteSnapshot 获取目标URL。 ActivatedRouteSnapshot中的routeConfig属性具有提供目标网址的path属性。

我已经按照上述方案进行了测试, 现在的路线如下所示,

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。