Reputation: 365
I have sidenav setup in the home page of my angular application. I have also setup links to other components in the sidenav. Now I want the components to load in the same space when their links are clicked with the sidenav and toolbar not getting affected.
The HTML file of the home page with the sidenav and toolbar
<mat-toolbar>
<button (click)='sidenav.toggle()'><mat-icon style="color: white">menu</mat-icon></button>
<b style="font-size: 22px; color: white">Hello {{user}}</b>
<nav>
<ul>
<li><button (click)='logout()'><div style='font-size: 19px; color: white'> LOGOUT</div></button></li>
</ul>
</nav>
</mat-toolbar>
<mat-sidenav-container>
<mat-sidenav #sidenav mode='side' [(opened)]='opened'>
<mat-nav-list style="margin-top: 50px">
<a mat-list-item routerLink="/dashboard" routerLinkActive="active"><button (click)='sidenav.close()'><mat-icon>dashboard</mat-icon><span> </span>DASHBOARD</button></a>
<a mat-list-item routerLink="/visual" routerLinkActive="active"><button (click)='sidenav.close()'><mat-icon>timeline</mat-icon><span> </span>VISUALISATION</button></a>
<a mat-list-item routerLink="/config" routerLinkActive="active"><button (click)='sidenav.close()'><mat-icon>settings</mat-icon><span> </span>PROFILE</button></a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
</mat-sidenav-content>
</mat-sidenav-container>
I want to ensure that when I open this page for the first time, dashboard will be displayed, but when i click in visualisation or profile, the dashboard component should be replaced by the other clicked component in the same place whithout the need to reload the toolbar and sidenav components.
Upvotes: 2
Views: 1640
Reputation: 365
To ensure that the sidenav acts as a navigation bar first we will need to specify the tag inside the tag. Then the second step is to specify the router links in the sidenav links. Ensure that the router links that they point to are specified as child routes of the main component. To specify them go to the app-routing.module.ts module and specify the routes which in the above case would be :
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { DashboardViewComponent } from './dashboard-view/dashboard-view.component';
import { VisualisationComponent } from './visualisation/visualisation.component';
import { ConfgaccountComponent } from './confgaccount/confgaccount.component';
const routes: Routes = [
{
path: 'dashboard', component: DashboardComponent, children: [
{ path: 'dash', component: DashboardViewComponent },
{ path: 'visual', component: VisualisationComponent },
{ path: 'config', component: ConfgaccountComponent },
]
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Now the next step would be to specify the tags inside the tags to ensure that the whenever the links in the sidenav are clicked they are routed to the proper child component and it is displayed in the correct place. Also ensure that the routerLinks inside the tags are updated to the proper routes specified for the child components, as present in the app-routing.module.ts file. The modified HTML code will be :
<mat-toolbar>
<button (click)='sidenav.toggle()'><mat-icon style="color: white">menu</mat-icon></button>
<b style="font-size: 22px; color: white">Hello {{user}}</b>
<nav>
<ul>
<li><button (click)='logout()'><div style='font-size: 19px; color: white'> LOGOUT</div></button></li>
</ul>
</nav>
</mat-toolbar>
<mat-sidenav-container>
<mat-sidenav #sidenav mode='side' [(opened)]='opened'>
<mat-nav-list style="margin-top: 50px">
<a mat-list-item routerLink="/dashboard/dash" routerLinkActive="active"><button (click)='sidenav.close()'><mat-icon>dashboard</mat-icon><span> </span>DASHBOARD</button></a>
<a mat-list-item routerLink="/dashboard/visual" routerLinkActive="active"><button (click)='sidenav.close()'><mat-icon>timeline</mat-icon><span> </span>VISUALISATION</button></a>
<a mat-list-item routerLink="/dashboard/config" routerLinkActive="active"><button (click)='sidenav.close()'><mat-icon>settings</mat-icon><span> </span>PROFILE</button></a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<main>
<router-outlet></router-outlet>
</main>
</mat-sidenav-content>
</mat-sidenav-container>
The next step is to create a navigation service to which the router and sidenav subscribe to to ensure the smooth routing to proper components whenever the links are clicked. The service needs to be injected into the constructor of the main dashboard component to ensure it's successful working. The nav.service.ts file will have contents as specified :
import { Injectable, EventEmitter } from '@angular/core';
import { Event, NavigationEnd, Router } from '@angular/router';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class NavService {
public appDrawer: any;
public currentUrl = new BehaviorSubject<string>(undefined);
constructor(private router: Router) {
this.router.events.subscribe((event: Event) => {
if (event instanceof NavigationEnd) {
this.currentUrl.next(event.urlAfterRedirects);
}
});
}
}
Finally test the successful working of the child components in the main dashboard component. The sidenav will successfully help in proper navigation among child components now.
Upvotes: 4