如何从Angular2中的父组件获取子路由的:id参数
Posted
技术标签:
【中文标题】如何从Angular2中的父组件获取子路由的:id参数【英文标题】:How to get :id param of child route from parent component in Angular2 【发布时间】:2017-05-24 00:35:41 【问题描述】:我正在尝试获取在
中定义的:id
参数
RouterModule.forRoot([
path: 'orders',
component: ListComponent,
children: [
path: 'view/:id',
component: ViewComponent
,
]
])
来自ListComponent
。
我已经试过了:
route: ActivatedRoute
route.params.subscribe(params =>
let id = +params['id'];
)
来自ListComponent
,但是params
数组是空的,我想这是因为:id
参数属于ViewComponent
而不是ListComponent
。
如何在ListComponent
中获取id
参数?
【问题讨论】:
【参考方案1】:另一种方法是在父组件中添加以下内容:
<ng-container *ngIf="routerOutlet.isActivated && routerOutlet.activatedRoute?.paramMap | async as paramMap">
child id is: paramMap.get('id')!
</ng-container>
<router-outlet #routerOutlet="outlet"></router-outlet>
当然,在子节点上使用解析器而不是参数会更好
<ng-container *ngIf="routerOutlet.activatedRouteData['child'] as child">
child id is : child.id
</ng-container>
<router-outlet #routerOutlet="outlet"></router-outlet>
假设子路由有类似的东西:
// ...
resolve:
child: 'childResolver',
,
子解析器可以在某个模块中:
// ...
providers: [
provide: 'childResolver',
useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => (
id: route.paramMap.get('id')
)
],
【讨论】:
【参考方案2】:递归查找子参数不会总能得到您正在寻找的参数。特别是在移动路线时。
相反,可以使用 RxJS ReplaySubject
发布当前子 ID。
创建一个新服务:
@Injectable()
export class ChildIdService
current$ = new ReplaySubject<number>();
在子组件上导入并订阅重播主题:
export class ChildComponent implements OnInit
constructor(private ar: ActivatedRoute, public ci: ChildIdService)
ngOnInit()
this.ar.params.map(params => +params.id).subscribe(this.ci.current$);
在父组件上导入服务,使用异步管道订阅子值:
<span>Mother component child ID: ci.current$ | async</span>
这是一个有效的 sn-p:https://stackblitz.com/edit/angular-b8xome(将 /child/42 添加到浏览器应用预览以查看它是否有效)
或者将组件定义为同级并将父级添加为无组件路由,例如:https://vsavkin.com/the-powerful-url-matching-engine-of-angular-router-775dad593b03 在“使用相同数据的同级组件”下
【讨论】:
使用 ReplaySubject 而不是其他类型的主题有什么特别的原因吗?我仍在尝试掌握它们的用例,因此在这个示例中理解它会有所帮助。 ReplaySubject 将记住之前的结果,使 observable 对任何未来的订阅都是热的。如果您在多个地方订阅了这个 observable,并且想要访问之前推送的结果,这将很有帮助。【参考方案3】:为了在父组件中获取子组件的参数,我使用了 ActivatedRoute 的 firstChild 属性,因为我只有子路由
route: ActivatedRoute
route.firstChild.params.subscribe(params =>
let id = +params['id'];
);
【讨论】:
唯一正确的答案,因为在 Angular 中事情永远不会同步发生,而且这个答案也涵盖了订阅(异步)部分。【参考方案4】:您可以使用firstChild
属性或ActivatedRoute
来获取子路由:
route.firstChild.snapshot.params['id']
【讨论】:
看起来属性 routerState 在 ActivatedRoute 上不存在,我也想在父组件而不是子组件中获取 id,所以我使用了 route.firstChild.params 我有点误读了这个问题,并假设@runyard 回答了你真正想要的。我更新了我的答案。 我使用了 route.snapshot.firstChild,而不是 route.firstChild.snapshot 还要检查 firstChild 是先定义的 在子加载之前不会有子参数。例如,您可以将 ActivatedRoute 注入子组件,并使子组件将参数传递给共享服务。 它正在工作,但我在控制台中遇到错误,类似“错误错误:ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:'true'。当前值:'false'”【参考方案5】:如果只有一个子路由,您可以继续挖掘route.firstChild.params['id']
,或者使用route.children[0].children[1].params['id']
之类的东西使用括号表示法来挖掘多个级别以访问同级路由。在找到正确的水平时,它有点反复试验。
【讨论】:
以上是关于如何从Angular2中的父组件获取子路由的:id参数的主要内容,如果未能解决你的问题,请参考以下文章
Angular 2 @Input - 如何从父组件绑定子组件的 ID 属性?
从 Angular2 路由中的子组件调用 router.parent.navigate 方法时未触发组件构造函数和路由器生命周期挂钩