Reputation: 40946
Using Angular 2 rc.1 and TypeScript. I'm having a lot of trouble passing routing parameters to my component when the component is loaded in a subroute. I use the @angular/router-deprecated
package.
In my root component, I configured the routes as such:
@RouteConfig([
{path:'/top', name:'Top', component: EndPointComponent},
{path:'/sub/...', name:'Sub', component: MiddleManComponent}
])
Here is the endpoint component where I attempt to read the parameters
import {Component} from '@angular/core';
import {RouteParams} from '@angular/router-deprecated';
@Component({
template: 'Route Params: {{routeParams.params | json}}'
})
export class EndPointComponent{
constructor(private routeParams:RouteParams){}
}
Here is the middleman component with the subroute to EndPointComponent
import {Component} from '@angular/core';
import {RouteConfig, ROUTER_DIRECTIVES} from '@angular/router-deprecated';
import {EndPointComponent} from "./endpoint.component";
@Component({
directives: [ROUTER_DIRECTIVES]
template: `<router-outlet></router-outlet>`
})
@RouteConfig([
{path: '/end', name: 'End', component: EndPointComponent, useAsDefault: true}
])
export class MiddleManComponent {}
The parameters can be successfully read from the routeParams
object of EndPointComponent
when the component is loaded from the top-level route (eg: the route named 'Top' in the root component). However, the parameters are always empty when I navigate to EndPointComponent
by going throug MiddleManComponent
(eg: via the route named 'Sub' in the root component).
Do children routers scrub the parameters from parents before resolving the routes? That doesn't make much sense so I bet I'm missing something. My question is simply: how do I pass route parameters to a subroute?
PS: I tried to build a plunker to demo this setup but I gave up when I couldn't figure out why the application doesn't load.
Upvotes: 5
Views: 7177
Reputation: 33
Using @angular/[email protected]
, you can access the parent ActivatedRoute
with
export class ChildComponent implements OnInit {
parentRouteId: string;
constructor(private route: ActivatedRoute) {
}
ngOnInit() {
this.route.parent.params
.subscribe((params: Params) => this.parentRouteId = params['id']);
}
}
Upvotes: 3
Reputation: 1316
You can inject ActivatedRote
and take a snapshot, even easier:
constructor(private route: ActivatedRoute) {};
ngOnInit() {
console.log('one of my parents route param:', this.route.snapshot.parent.params['PARAM-NAME']);
}
Upvotes: 0
Reputation: 2781
Using the "@angular/router": "3.0.0-alpha.6" package, i was able to get the parent route argument by doing the following:
export class ChildComponent {
private sub: any;
private parentRouteId: number;
constructor(
private router: Router,
private route: ActivatedRoute) {
}
ngOnInit() {
this.sub = this.router.routerState.parent(this.route).params.subscribe(params => {
this.parentRouteId = +params["id"];
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
In this example the route has the following format: /parent/:id/child/:childid
export const routes: RouterConfig = [
{
path: '/parent/:id',
component: ParentComponent,
children: [
{ path: '/child/:childid', component: ChildComponent }]
}
];
Upvotes: 1
Reputation: 5724
Child routes actually get their own instance of RouteParams, distinct from the parent route's. This is done to avoid naming collisions and facilitate encapsulation of the routed component.
One way you can share a parent route's parameters with a component loaded by a child route is through a service.
@Injectable()
export class RouteParamService {
constructor(private routeParams: RouteParams) {}
get params() {
return this.routeParams.params;
}
}
@Component({
template: 'Route Params: {{routeParams.params | json}}'
})
export class EndPointComponent{
constructor(private routeParams:RouteParamService){}
}
@Component({
directives: [ROUTER_DIRECTIVES]
template: `<router-outlet></router-outlet>`,
providers: [RouteParamService]
})
@RouteConfig([
{path: '/end', name: 'End', component: EndPointComponent, useAsDefault: true}
])
class MiddleManComponent() { }
The RouteParamService will be instantiated at the same route level as the MiddleManComponent and so will get the same instance of RouteParams. When your service gets injected into your child route component, you'll be able to access the parent route params.
If you need 2 instances of EndPointComponent to load at different route tree levels, you'll need another tier of parent route, I think; i.e. a routed component that encapsulates both MiddleManComponent and EndPointComponent, between RootComponent.
RootComponent is not routed, so you won't be able to instantiate RouteParams for the RouteParamService from it. RouteParams is provided by the <router-outlet>
component.
Upvotes: 4