如何从Angular2中的父组件获取子路由的id参数

How to get :id param of child route from parent component in Angular2

我正在尝试获取

中定义的 :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 参数?

您可以使用firstChild 属性或ActivatedRoute获取子路由:

route.firstChild.snapshot.params['id']

如果只有一个子路由,您可以继续挖掘 route.firstChild.params['id'],或者使用 route.children[0].children[1].params['id'] 之类的东西来挖掘多个级别,使用括号表示法来访问兄弟路由。在找到正确的级别时需要反复试验。

为了在父组件中获取子组件的参数,我使用了 ActivatedRoute 的 firstChild 属性,因为我只有子路由

route: ActivatedRoute

route.firstChild.params.subscribe(params => {
  let id = +params['id'];
});

递归查找子参数并不总能找到您要查找的参数。特别是在移动路线时。

相反,可以使用 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>

这是一个有效的代码段:https://stackblitz.com/edit/angular-b8xome(将 /child/42 添加到浏览器应用程序预览中以查看它是否有效)


或者将组件定义为兄弟组件并将父组件添加为无组件路由,例如:https://vsavkin.com/the-powerful-url-matching-engine-of-angular-router-775dad593b03 under "Sibling Components Using Same Data"

另一种方法是在父组件中添加以下内容:

<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>

当然,最好在子节点上使用 have resolver 而不是 params

<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')
    })
  }],