Angular 2 - Submodule routing and nested <router-outlet>
AngularRoutesAngular Problem Overview
I'm looking for a solution with Angular 2 for the scenario explained below:
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"},
]
},
];