如何使用angular2中的link参数数组从子组件导航到上层路由?
How to navigate from child component to upper level routes using link params array in angular2?
我的 AppComponent 有一个定义顶级路由的 @RouteConfig 装饰器:
@RouteConfig([
{
path: '/',
name: 'Home',
component: HomeComponent
},
{
path: '/about',
name: 'About',
component: AboutComponent
},
{
path: '/profile/...',
name: 'Profile',
component: ProfileComponent
}
])
export class AppComponent {
}
我的 ProfileComponent 有一个 @RouteConfig 装饰器,它定义了 Profile 子路由:
@RouteConfig([
{path: '/', component: ProfileDetailsComponent, name: 'View', useAsDefault: true},
{path: '/:id', component: ProfileDetailsComponent, name: 'Public'},
{path: '/edit', component: ProfileEditorComponent, name: 'Edit'},
])
export class ProfileComponent {
}
当我在 ProfileDetailsComponent 中时,我可以重定向到其他配置文件路由,但不能重定向到其他路由。我想避免使用 navigateByUrl
指定 url,而是使用路由名称,使用 navigate
。例如:
this.router.navigate(['View']); // Works
this.router.navigate(['About']); // Raises error that it does not exist
我在这里阅读了这个答案:
它使用:
this.router.parent.navigate(['About']);
这还不错,但只有当我在声明时知道重定向应该去哪里时才能解决我的问题。我有多层嵌套并在运行时确定目标路由。我正在寻找一种方法来做类似的事情:
this.router.navigate(['Level1', 'Level2', 'Level3']);
这让我可以在某处跟踪目标路由的完全限定名称。这有可能吗?
这是微服务派上用场的地方,查看 service docs here。这个想法是 parent 可以侦听 child 导航请求,并且 child 可以根据需要广播所述更改。
让我们从一个简单的 object 开始,它将存储路由名称和可选参数:
export class NavArgs {
constructor(routeName: string, args?: any) { }
}
现在让我们定义微服务,rxjs
这真的很简单:
import { Injectable } from '@angular/core'
import { Subject } from 'rxjs/Subject';
@Injectable()
export class NavigationService {
private navigationRequestedSource = new Subject<string>();
onNavigationRequested$ = this.navigationRequestedSource.asObservable();
requestNaivation(navArg: string) {
this.navigationRequestedSource.next(mission)
}
}
现在 child 组件可以使用它并请求导航:
export class SomeChild {
constructor(navService: NavigationService) { }
invoke() {
this.navService.requestNaivation(new NavArgs('SomeRoute'));
}
}
并且 parent 组件可以侦听所述请求并对其执行操作:
export class SomeParent {
constructor(navService: NavigationService, router: Router) {
this.navService
.onNavigationRequested$
.subscribe((navArgs: NavArgs) => {
if (navArgs) {
if (navArgs.args) {
this.router.navigate([ navArgs.routeName, navArgs.args ]);
}
else {
this.router.navigate([ navArgs.routeName ]);
}
}
});
}
}
显然这是非常基本的代码示例,还需要更多的导入和错误处理等。但希望你明白了。
备注
重要的是要确保 parent 和 child 使用此服务的相同实例,为此您必须将其设置为 provider
使用它的最高级别。这是因为默认情况下 Angular2 为 DI 创建一个单例并使用分层方法。一定要保证不要误将其设置为较低级别的provider
,否则将无法正常工作。
在路由名称前加斜杠表示该路由是根路由
this.router.navigate(['/About']);
我的 AppComponent 有一个定义顶级路由的 @RouteConfig 装饰器:
@RouteConfig([
{
path: '/',
name: 'Home',
component: HomeComponent
},
{
path: '/about',
name: 'About',
component: AboutComponent
},
{
path: '/profile/...',
name: 'Profile',
component: ProfileComponent
}
])
export class AppComponent {
}
我的 ProfileComponent 有一个 @RouteConfig 装饰器,它定义了 Profile 子路由:
@RouteConfig([
{path: '/', component: ProfileDetailsComponent, name: 'View', useAsDefault: true},
{path: '/:id', component: ProfileDetailsComponent, name: 'Public'},
{path: '/edit', component: ProfileEditorComponent, name: 'Edit'},
])
export class ProfileComponent {
}
当我在 ProfileDetailsComponent 中时,我可以重定向到其他配置文件路由,但不能重定向到其他路由。我想避免使用 navigateByUrl
指定 url,而是使用路由名称,使用 navigate
。例如:
this.router.navigate(['View']); // Works
this.router.navigate(['About']); // Raises error that it does not exist
我在这里阅读了这个答案:
它使用:
this.router.parent.navigate(['About']);
这还不错,但只有当我在声明时知道重定向应该去哪里时才能解决我的问题。我有多层嵌套并在运行时确定目标路由。我正在寻找一种方法来做类似的事情:
this.router.navigate(['Level1', 'Level2', 'Level3']);
这让我可以在某处跟踪目标路由的完全限定名称。这有可能吗?
这是微服务派上用场的地方,查看 service docs here。这个想法是 parent 可以侦听 child 导航请求,并且 child 可以根据需要广播所述更改。
让我们从一个简单的 object 开始,它将存储路由名称和可选参数:
export class NavArgs {
constructor(routeName: string, args?: any) { }
}
现在让我们定义微服务,rxjs
这真的很简单:
import { Injectable } from '@angular/core'
import { Subject } from 'rxjs/Subject';
@Injectable()
export class NavigationService {
private navigationRequestedSource = new Subject<string>();
onNavigationRequested$ = this.navigationRequestedSource.asObservable();
requestNaivation(navArg: string) {
this.navigationRequestedSource.next(mission)
}
}
现在 child 组件可以使用它并请求导航:
export class SomeChild {
constructor(navService: NavigationService) { }
invoke() {
this.navService.requestNaivation(new NavArgs('SomeRoute'));
}
}
并且 parent 组件可以侦听所述请求并对其执行操作:
export class SomeParent {
constructor(navService: NavigationService, router: Router) {
this.navService
.onNavigationRequested$
.subscribe((navArgs: NavArgs) => {
if (navArgs) {
if (navArgs.args) {
this.router.navigate([ navArgs.routeName, navArgs.args ]);
}
else {
this.router.navigate([ navArgs.routeName ]);
}
}
});
}
}
显然这是非常基本的代码示例,还需要更多的导入和错误处理等。但希望你明白了。
备注
重要的是要确保 parent 和 child 使用此服务的相同实例,为此您必须将其设置为 provider
使用它的最高级别。这是因为默认情况下 Angular2 为 DI 创建一个单例并使用分层方法。一定要保证不要误将其设置为较低级别的provider
,否则将无法正常工作。
在路由名称前加斜杠表示该路由是根路由
this.router.navigate(['/About']);