Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting content of named router-outlet in child route

In my application I want to display content in two router-outlets, the primary one and a named one. If I place both outlets on the root level, I am able to set the content of the named outlet like this:

this.router.navigate([{ outlets: { rootSecondary: ['rootSecondaryPath'] } }]);

However, I want the general layout of the application to provide a single router-outlet and be able to use a different router-outlet structure in the child routes.

If I create a child route, that also has a primary and a named outlet, I am unable to set the content of the secondary outlet. The error that is reported is:

Cannot match any routes.

The routes are defined as follows:

const appRoutes: Routes = [
  { path: '', component: RootPrimaryComponent },
  { path: 'rootSecondaryPath', component: RootSecondaryComponent, outlet: 'rootSecondary' },
  {
    path: 'child', component: ChildComponent, children:
      [
        { path: '', component: ChildPrimaryComponent },
        { path: 'childSecondaryPath', component: ChildSecondaryComponent, outlet: 'childSecondary' },
      ]
  },
];
const appRouting = RouterModule.forRoot(appRoutes);

The template of app.component.html contains a primary outlet and - for testing purposes - a named secondary one:

<router-outlet></router-outlet>
<div style="border: solid 1px green">
  <router-outlet name="rootSecondary"></router-outlet>
</div>

The code above is called from a button and sets the rootSecondary outlet without any problem.

The template child.component.html defines two outlets that are placed inside of the root primary outlet:

<router-outlet></router-outlet>
<div style="border:solid 1px red">
  <router-outlet name="childSecondary"></router-outlet>
</div>

child.primary.component.html contains a button that calls the code to set the secondary outlet:

<div>
  child-primary works!
  <button (click)="setChildSecondary()">Set child secondary</button>
</div>

When clicked, the following code is run:

setChildSecondary() {
  this.router.navigate([{ outlets: { childSecondary: ['childSecondaryPath'] } }]);
}

How do I have to change the code so that the router-outlet childSecondary is filled?

like image 276
Markus Avatar asked Dec 08 '17 20:12

Markus


People also ask

Is it possible to have a multiple router outlet in the same template?

You can have multiple router-outlet in same template by configuring your router and providing name to your router-outlet, you can achieve this as follows. Advantage of below approach is thats you can avoid dirty looking URL with it. eg: /home(aux:login) etc. Assuming on load you are bootstraping appComponent.

Which property is used to define child routes within a routes object?

In Angular, the router lets you add child routes using the children property inside the routing module. Here you can see that the routing module has been updated with the child route and added to the array of components so we do not need to import all of them wherever we go.

Where are child URL routes defined?

Just like we had a <router-outlet></router-outlet> for the root application component, we would have a router outlet inside the ProductDetails component. The components corresponding to the child routes of product-details would be placed in the router outlet in ProductDetails .


1 Answers

In order to solve this, I needed to set the relativeTo param to the parent of the currently active route:

export class ChildPrimaryComponent {

  constructor(private readonly router: Router,
    private readonly route: ActivatedRoute) { }

  setChildSecondary() {
    this.router.navigate([{ outlets: { childSecondary: ['childSecondaryPath'] } }],
      { relativeTo: this.route.parent });
  }
}
like image 68
Markus Avatar answered Oct 03 '22 05:10

Markus