Angular 2 - Submodule routing and nested <router-outlet>

AngularRoutes

Angular Problem Overview


I'm looking for a solution with Angular 2 for the scenario explained below:

enter image description here

In this scenario, the top-nav contains links to load submodules and sub-nav has links to update the submodule's contents.

The URLs should map as:

  • /home => loads the home page in main component router outlet
  • /submodule => loads the submodule in the main component router outlet and by default should show the submodule's home page and sub navbar
  • /submodule/feature => loads the feature inside the submodule's router outlet

The app module (and app component) contains a top navbar to navigate to different submodules and the app component template could look like this

<top-navbar></top-navbar>
<router-outlet></router-outlet>

But here is the complexity. I need my submodules to have a similar layout with a second level nav bar and their own router outlet to load their own components.

<sub-navbar></sub-navbar>
<router-outlet name='sub'></router-outlet>

I tried every option and search everywhere but couldn't find a solution to have a default template (like app component) in the sub-module with router outlet and also load the contents of submodule in the inner router outlet without losing the sub-nav.

I would appreciate any input or ideas

Angular Solutions


Solution 1 - Angular

The html page will look like this.

Main Page

<top-navbar></top-navbar>
<router-outlet></router-outlet>

Sub Module Page

<sub-navbar></sub-navbar>
<router-outlet name='sub'></router-outlet>

on clicking navigation in top-nav bar the main route outlet will route respectively.

while clicking on sub-navbar the router-outlet [sub] will route respectively.

HTML is fine, the trick will came at writing app.routing

app.routing.ts

const appRoutes: Routes = [
  {
    path: 'login',
    component: LoginComponent
  },
  { path: 'home',
    component: homeComponent,
    children: [
      {
        path: 'module1',
        component: module1Component,
        children: [
          {
            path: 'submodule11',
            component: submodule11Component,
          },
          {
            path: '',
            redirectTo: 'submodule11',
            pathMatch: 'full'
          }
        ]
      },
      {
        path: 'module2',
        component: module2omponent,
        children: [
          {
            path: 'submodule21',
            component: submodule21Component,
          },
          {
            path: '',
            redirectTo: 'submodule21',
            pathMatch: 'full'
          }
        ]
      }
    ]
  },
  {
    path: 'about',
    component: aboutComponent
  }
]

Hope it will help you.

More details https://angular.io/guide/router

Solution 2 - Angular

Use:

RouterModule.forChild()
...
<router-outlet name="sub"></router-outlet>
...
[routerLink]="[{ outlets: { sub: [subRouteName] } }]"

Full example:

HTML

<div class="tabs tinyscroll">
  <button *ngFor="let tab of tabs"
  [routerLink]="[{ outlets: { sub: [tab.name] } }]"
  routerLinkActive="selected">
    <span>{{ tab.label }}</span>
  </button>
</div>

<section>
  <router-outlet name="sub"></router-outlet>
</section>

app.module.ts

imports: [
...
    RouterModule.forChild([
      {
        path: 'registers',
        component: RegistersComponent,
        children: [
          {path: 'vehicles', component: VehiclesComponent, outlet: 'sub'},
          {path: 'drivers', component: DriversComponent, outlet: 'sub'},
          {path: 'bases', component: BasesComponent, outlet: 'sub'},
          {path: 'lines', component: LinesComponent, outlet: 'sub'},
          {path: 'users', component: UsersComponent, outlet: 'sub'},
          {path: 'config', component: ConfigComponent, outlet: 'sub'},
          {path: 'companies', component: CompaniesComponent, outlet: 'sub'}
        ],
        canActivate: [AuthGuard]
      }
    ]),
...

Solution 3 - Angular

you have to mention the outlet name in the routes mention your router outlet name in the routing like this "outlet:'sub"

routes: Routes = [
  {path:'', redirectTo: 'login', pathMatch: 'full'},
  {
    path: 'login',
    component: LoginComponent,
    
  },
  { path: 'home',
    component: AppComponent,
      children: [
        {path: 'home/pdf',component: SideMenuPage,outlet:"sub" },
        {path:'home/addFileUp',component:SidePageAdd,outlet:"sub"},
      ]
   },
];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRon FView Question on Stackoverflow
Solution 1 - AngularAswin KVView Answer on Stackoverflow
Solution 2 - AngularthxmxxView Answer on Stackoverflow
Solution 3 - AngularNambi N RajanView Answer on Stackoverflow