Reputation: 11187
Running Angular 8. My main navigation has a set of links one being, for example /services
. On that page are services. When a user clicks "Production" it goes to the url /services/production
however, the "Services" nav item loses it's active state.
I've applied [routerLinkActiveOptions]="{exact: false}"
to attempt enforce the active classes on non-exact routes but it's not maintaining the active state.
the routes for these are in their individual directories so "services" has a services-routing.module
that handles it's routing. However the navigation links are the root/app level.
I think I need load those routes into the app-routing.module
but not sure how to go about that, if that's the case.
When attempting to lazy load the routes I get the error:
Error: BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.
I double checked and made sure I'm only importing BrowserModule
and BrowserAnimationsModule
at the app.module
level.
--- edit
I have the routes lazy loading but that didn't resolve it. /services
shows active but /services/production
doesn't
--- edit
app-routing.module:
const routes: Routes = [
{ path: 'logout', component: LogoutComponent },
{ path: 'access-denied', component: AccessDeinedComponent }
];
app.component
this.navLinks = [
{ path: '/about', label: 'About', icon: 'assessment' },
{ path: '/contact', label: 'Contact', icon: 'assignment' },
{ path: '/services', label: 'Services', icon: 'settings' }
];
app.component.html
<nav class="nav-tab-group" mat-tab-nav-bar color="accent">
<a mat-tab-link *ngFor="let link of navLinks"
[routerLink]="link.path"
routerLinkActive="mat-tab-label-active active-link"
class="subnav-link">
<mat-icon class="tab-icon">{{link.icon}} is view</mat-icon>
<span class="link-text" >{{link.label}}</span>
</a>
</nav>
services-routing.module (in a different directory)
const routes: Routes = [
{
path: '',
component: ServicesComponent,
canActivate: [AuthGuardService],
data: { roles },
children: [
{
path: 'services/production',
component: ProductionComponent,
canActivate: [AuthGuardService],
data: { roles }
}...
]
}
];
So the actual route behavior in in the services-routing.module and the nav in in the root app.component scripts. When I"m at the services root, the services routerLink
is active but all children it's inactive.
Upvotes: 2
Views: 3209
Reputation: 11187
The solution I've landed on is adding my active link class conditionally:
[ngClass]="{'active-link': setActiveNav(link)}"
my navLinks
variable has an addition string[]
that hold other acceptable paths, for example ['/services/production']
.
The method that returns true looks for the existence of additional paths and check if it exists in location.path()
using the Location class from @angular/common
. It also checks against the expected path.
I also have an situation where a nav item needs to be "active" on a completely unrelated URL.
setActiveNav(navLink): boolean {
const currentPath = this.location.path();
let foundPath = false;
if (navLink.additionalPaths) {
navLink.additionalPaths.forEach(path => {
if (currentPath.indexOf(path) >= 0 || currentPath.indexOf(navLink.path) >= 0) {
foundPath = true;
}
});
} else if (currentPath.indexOf(navLink.path) >= 0) {
foundPath = true;
}
return foundPath;
}
Upvotes: 1