问题描述
我们在这里提供了子路由定义,其中我们使用了一个守卫来检查用户在使用我们的服务之前是否接受了条款.
We have child routes definitions presented here, in which we use a guard to check if the user has accepted terms before using our service.
account/secret/secret.routes.ts:
import { Routes } from '@angular/router';
import { SecretFormComponent } from './secret-form.component';
import { SecretTermsComponent } from './secret-terms.component';
import { TermsGuard } from './services/terms-guard.service';
export const secretRoutes: Routes = [
{
path: '',
redirectTo: 'form'
},
{
path: 'form',
component: SecretFormComponent,
canActivate: [TermsGuard]
},
{ path: 'terms', component: SecretTermsComponent }
// otherwise redirect to form
{ path: '**', redirectTo: 'form' }
];
在我们的terms-guard中,我们定义了这个代码:
In our terms-guard, we have defined this code:
this.router.navigate(['/account/secret/terms']);
return false;
有没有办法在路由组"中使用相对路由导航进行重定向?因为如果有一天我们的帐户网站仪表板重命名为诸如 my-account 之类的任何其他内容,则定义绝对路径可能会中断.我们希望我们的秘密模块可以重复使用.
Is there a way to redirect using relative route navigation from within a "routing group"? Because defining an absolute path may be break if one day our account website dashboard is renamed to anything else like my-account for example. We want our secret module to be reusable.
我希望能够在我的守卫中导航到 ['./terms']
但它不起作用,就像守卫不知道从哪里"到开始相对导航.
I'd like to be able to navigate to ['./terms']
in my guard but it doesn't work, just like the guard doesn't know "from where" to start relative navigation.
推荐答案
你要使用的是你的守卫的canActivate
方法的RouterStateSnapshot
参数.
What you want to use is the RouterStateSnapshot
parameter of the canActivate
method of your guard.
>
RouterStateSnapshot
包含您正在路由到的当前路径,而 Router.url
是您路由的当前路径(这就是为什么 @Günter Zöchbauer 的回答在这种情况下不太适用.
The RouterStateSnapshot
has the current path you are in the process of routing to, whereas the Router.url
is the current path your are routing from (which is why @Günter Zöchbauer's answer doesn't quite work in this scenario).
为了在没有额外代码的情况下完全适用于您的用例,您需要将路由更改为
For this to apply completely to your use case without additional code you will want to change your routes to
/account/secret/form
和 /account/secret/form/terms
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class ChildRouteGuard implements CanActivate {
constructor(private router: Router) { }
canActivate(_route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
// user can view the specific route
if (...) {
return true;
}
// else route them to a variation of the route
this.router.navigate([state.url, 'terms']);
return false;
}
}
编辑 1
您还可以利用 ActivatedRouteSnapshot
来保留当前的 url 结构,如下所示
Edit 1
You could keep your current url structure by also taking advantage of the ActivatedRouteSnapshot
as seen below
假设路由像 account/secret/form
和 account/secret/terms
route.url
是一个 url 段数组,我们想要最后一个,因为那将是 form
.我们在当前路径中找到它的索引,我们尝试去account/secret/form
并slice
把它切掉.在这一点上,我们有我们试图导航到 account/secret
的当前路由的父",我们可以将兄弟添加到 form
,即 条款
.
route.url
is an array of url segments, we want the last one because that is going to be form
. We find the index of that in the current route we are trying to go to account/secret/form
and slice
it out. At this point we have the 'parent' of the current route we are trying to navigate to account/secret
and we can add on the sibling to form
which is terms
.
注意:当您在 url 中重复出现 form
时,此模式会失效
Note: this pattern breaks down when you have repeated occurrences of form
in your url
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class ChildRouteGuard implements CanActivate {
constructor(private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
// user can view the specific route
if (...) {
return true;
}
let parentUrl = state.url
.slice(0, state.url.indexOf(route.url[route.url.length - 1].path));
this.router.navigate([parentUrl, 'terms']);
return false;
}
}
这篇关于Angular2 相对路线在警卫中导航的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!