如何从子路由导航到父路由?
How do I navigate to a parent route from a child route?
我的问题比较经典。我有一个应用程序的私有部分,它位于 login form
之后。登录成功后,会转到admin应用的子路由。
我的问题是我无法使用 global navigation menu
,因为路由器试图在我的 AdminComponent
而不是我的 AppCompoment
中进行路由。所以我的导航坏了。
还有一个问题是,如果有人想直接访问URL,我想重定向到父"login"路由。但我无法让它发挥作用。在我看来,这两个问题很相似。
知道怎么做吗?
从 @angular/common
向您的构造函数添加 Location
constructor(private _location: Location) {}
添加后退功能:
back() {
this._location.back();
}
然后在您看来:
<button class="btn" (click)="back()">Back</button>
constructor(private router: Router) {}
navigateOnParent() {
this.router.navigate(['../some-path-on-parent']);
}
路由器支持
- 绝对路径
/xxx
- 在根组件的路由器上启动
- 相对路径
xxx
- 在当前组件的路由器上启动
- 相对路径
../xxx
- 在当前组件的父路由器上启动
您想要 link/HTML 还是路由 imperatively/in 代码?
Link:RouterLink 指令始终将提供的 link 视为当前 URL 的增量:
[routerLink]="['/absolute']"
[routerLink]="['../../parent']"
[routerLink]="['../sibling']"
[routerLink]="['./child']" // or
[routerLink]="['child']"
// with route param ../../parent;abc=xyz
[routerLink]="['../../parent', {abc: 'xyz'}]"
// with query param and fragment ../../parent?p1=value1&p2=v2#frag
[routerLink]="['../../parent']" [queryParams]="{p1: 'value', p2: 'v2'}" fragment="frag"
使用路由器Link,记得导入并使用directives
数组:
import { ROUTER_DIRECTIVES } from '@angular/router';
@Component({
directives: [ROUTER_DIRECTIVES],
命令式[=26=]:navigate()
方法需要一个起点(即 relativeTo
参数)。如果提供none,则导航是绝对的:
import { Router, ActivatedRoute } from '@angular/router';
...
constructor(private router: Router, private route: ActivatedRoute) {}
...
this.router.navigate(["/absolute/path"]);
this.router.navigate(["../../parent"], {relativeTo: this.route});
this.router.navigate(["../sibling"], {relativeTo: this.route});
this.router.navigate(["./child"], {relativeTo: this.route}); // or
this.router.navigate(["child"], {relativeTo: this.route});
// with route param ../../parent;abc=xyz
this.router.navigate(["../../parent", {abc: 'xyz'}], {relativeTo: this.route});
// with query param and fragment ../../parent?p1=value1&p2=v2#frag
this.router.navigate(["../../parent"], {relativeTo: this.route,
queryParams: {p1: 'value', p2: 'v2'}, fragment: 'frag'});
// navigate without updating the URL
this.router.navigate(["../../parent"], {relativeTo: this.route, skipLocationChange: true});
从 Spring 2017 年开始,这似乎对我有用:
goBack(): void {
this.router.navigate(['../'], { relativeTo: this.route });
}
您的组件 ctor 接受 ActivatedRoute
和 Router
,导入如下:
import { ActivatedRoute, Router } from '@angular/router';
导航到父组件,不管当前路由或父路由中的参数个数:Angular 6更新1/ 21/19
let routerLink = this._aRoute.parent.snapshot.pathFromRoot
.map((s) => s.url)
.reduce((a, e) => {
//Do NOT add last path!
if (a.length + e.length !== this._aRoute.parent.snapshot.pathFromRoot.length) {
return a.concat(e);
}
return a;
})
.map((s) => s.path);
this._router.navigate(routerLink);
这有一个额外的好处,就是可以与单例路由器一起使用的绝对路由。
(Angular 肯定是 4+,也可能是 Angular 2。)
我的路线有这样的模式:
- user/edit/1 -> 编辑
- user/create/0 -> 创建
- 用户/ -> 列表
例如,当我在编辑页面上时,我需要返回列表页面,我会return在路线上向上 2 层。
考虑到这一点,我创建了带有 "level" 参数的方法。
goBack(level: number = 1) {
let commands = '../';
this.router.navigate([commands.repeat(level)], { relativeTo: this.route });
}
所以,为了从编辑到列表,我调用了这样的方法:
this.goBack(2);
您可以像这样导航到您的父根目录
this.router.navigate(['.'], { relativeTo: this.activeRoute.parent });
您需要在构造函数中注入当前活动的路由
constructor(
private router: Router,
private activeRoute: ActivatedRoute) {
}
另一种方式可能是这样
this._router.navigateByUrl(this._router.url.substr(0, this._router.url.lastIndexOf('/'))); // go to parent URL
这是构造函数
constructor(
private _activatedRoute: ActivatedRoute,
private _router: Router
) { }
事不宜迟:
this.router.navigate(['..'], {relativeTo: this.activeRoute, skipLocationChange: true});
参数'..' 使导航上一级,即父级:)
如果您使用的是 uiSref 指令,那么您可以这样做
uiSref="^"
我的解决方案是:
const urlSplit = this._router.url.split('/');
this._router.navigate([urlSplit.splice(0, urlSplit.length - 1).join('/')], { relativeTo: this._route.parent });
和 Router
注入:
private readonly _router: Router
None 这对我有用...这是我的带有后退功能的代码:
import { Router } from '@angular/router';
...
constructor(private router: Router) {}
...
back() {
this.router.navigate([this.router.url.substring(0, this.router.url.lastIndexOf('/'))]);
}
this.router.url.substring(0, this.router.url.lastIndexOf('/') --> 获取当前url中“/”后的最后一部分 --> 获取当前路由.
这可能有帮助:https://angular.io/api/router/ExtraOptions#relativeLinkResolution
ExtraOptions interface
A set of configuration options for a router module, provided in the forRoot() method.
interface ExtraOptions {
// Others omitted
relativeLinkResolution?: 'legacy' | 'corrected'
}
relativeLinkResolution?: 'legacy' | 'corrected'
Enables a bug fix that corrects relative link resolution in components with empty paths.
<<snip>>
The default in v11 is corrected.
最近几天我一直在为路由问题苦苦挣扎,结果发现相对路由曾经有一个错误。这修复了它。
我的问题比较经典。我有一个应用程序的私有部分,它位于 login form
之后。登录成功后,会转到admin应用的子路由。
我的问题是我无法使用 global navigation menu
,因为路由器试图在我的 AdminComponent
而不是我的 AppCompoment
中进行路由。所以我的导航坏了。
还有一个问题是,如果有人想直接访问URL,我想重定向到父"login"路由。但我无法让它发挥作用。在我看来,这两个问题很相似。
知道怎么做吗?
从 @angular/common
constructor(private _location: Location) {}
添加后退功能:
back() {
this._location.back();
}
然后在您看来:
<button class="btn" (click)="back()">Back</button>
constructor(private router: Router) {}
navigateOnParent() {
this.router.navigate(['../some-path-on-parent']);
}
路由器支持
- 绝对路径
/xxx
- 在根组件的路由器上启动 - 相对路径
xxx
- 在当前组件的路由器上启动 - 相对路径
../xxx
- 在当前组件的父路由器上启动
您想要 link/HTML 还是路由 imperatively/in 代码?
Link:RouterLink 指令始终将提供的 link 视为当前 URL 的增量:
[routerLink]="['/absolute']"
[routerLink]="['../../parent']"
[routerLink]="['../sibling']"
[routerLink]="['./child']" // or
[routerLink]="['child']"
// with route param ../../parent;abc=xyz
[routerLink]="['../../parent', {abc: 'xyz'}]"
// with query param and fragment ../../parent?p1=value1&p2=v2#frag
[routerLink]="['../../parent']" [queryParams]="{p1: 'value', p2: 'v2'}" fragment="frag"
使用路由器Link,记得导入并使用directives
数组:
import { ROUTER_DIRECTIVES } from '@angular/router';
@Component({
directives: [ROUTER_DIRECTIVES],
命令式[=26=]:navigate()
方法需要一个起点(即 relativeTo
参数)。如果提供none,则导航是绝对的:
import { Router, ActivatedRoute } from '@angular/router';
...
constructor(private router: Router, private route: ActivatedRoute) {}
...
this.router.navigate(["/absolute/path"]);
this.router.navigate(["../../parent"], {relativeTo: this.route});
this.router.navigate(["../sibling"], {relativeTo: this.route});
this.router.navigate(["./child"], {relativeTo: this.route}); // or
this.router.navigate(["child"], {relativeTo: this.route});
// with route param ../../parent;abc=xyz
this.router.navigate(["../../parent", {abc: 'xyz'}], {relativeTo: this.route});
// with query param and fragment ../../parent?p1=value1&p2=v2#frag
this.router.navigate(["../../parent"], {relativeTo: this.route,
queryParams: {p1: 'value', p2: 'v2'}, fragment: 'frag'});
// navigate without updating the URL
this.router.navigate(["../../parent"], {relativeTo: this.route, skipLocationChange: true});
从 Spring 2017 年开始,这似乎对我有用:
goBack(): void {
this.router.navigate(['../'], { relativeTo: this.route });
}
您的组件 ctor 接受 ActivatedRoute
和 Router
,导入如下:
import { ActivatedRoute, Router } from '@angular/router';
导航到父组件,不管当前路由或父路由中的参数个数:Angular 6更新1/ 21/19
let routerLink = this._aRoute.parent.snapshot.pathFromRoot
.map((s) => s.url)
.reduce((a, e) => {
//Do NOT add last path!
if (a.length + e.length !== this._aRoute.parent.snapshot.pathFromRoot.length) {
return a.concat(e);
}
return a;
})
.map((s) => s.path);
this._router.navigate(routerLink);
这有一个额外的好处,就是可以与单例路由器一起使用的绝对路由。
(Angular 肯定是 4+,也可能是 Angular 2。)
我的路线有这样的模式:
- user/edit/1 -> 编辑
- user/create/0 -> 创建
- 用户/ -> 列表
例如,当我在编辑页面上时,我需要返回列表页面,我会return在路线上向上 2 层。
考虑到这一点,我创建了带有 "level" 参数的方法。
goBack(level: number = 1) {
let commands = '../';
this.router.navigate([commands.repeat(level)], { relativeTo: this.route });
}
所以,为了从编辑到列表,我调用了这样的方法:
this.goBack(2);
您可以像这样导航到您的父根目录
this.router.navigate(['.'], { relativeTo: this.activeRoute.parent });
您需要在构造函数中注入当前活动的路由
constructor(
private router: Router,
private activeRoute: ActivatedRoute) {
}
另一种方式可能是这样
this._router.navigateByUrl(this._router.url.substr(0, this._router.url.lastIndexOf('/'))); // go to parent URL
这是构造函数
constructor(
private _activatedRoute: ActivatedRoute,
private _router: Router
) { }
事不宜迟:
this.router.navigate(['..'], {relativeTo: this.activeRoute, skipLocationChange: true});
参数'..' 使导航上一级,即父级:)
如果您使用的是 uiSref 指令,那么您可以这样做
uiSref="^"
我的解决方案是:
const urlSplit = this._router.url.split('/');
this._router.navigate([urlSplit.splice(0, urlSplit.length - 1).join('/')], { relativeTo: this._route.parent });
和 Router
注入:
private readonly _router: Router
None 这对我有用...这是我的带有后退功能的代码:
import { Router } from '@angular/router';
...
constructor(private router: Router) {}
...
back() {
this.router.navigate([this.router.url.substring(0, this.router.url.lastIndexOf('/'))]);
}
this.router.url.substring(0, this.router.url.lastIndexOf('/') --> 获取当前url中“/”后的最后一部分 --> 获取当前路由.
这可能有帮助:https://angular.io/api/router/ExtraOptions#relativeLinkResolution
ExtraOptions interface
A set of configuration options for a router module, provided in the forRoot() method.interface ExtraOptions { // Others omitted relativeLinkResolution?: 'legacy' | 'corrected' }
relativeLinkResolution?: 'legacy' | 'corrected'
Enables a bug fix that corrects relative link resolution in components with empty paths.
<<snip>>
The default in v11 is corrected.
最近几天我一直在为路由问题苦苦挣扎,结果发现相对路由曾经有一个错误。这修复了它。