To achieve your goal, you will need to implement some custom logic to save and manage the state effectively.
There are two approaches you can take to accomplish this task, outlined below:
- Utilize unique routes: By using
routerLink
, you can easily determine the active route based on the router configuration. This method does not support the use of catchall routes like **
due to its reliance on the router settings.
- Implement a state management system with Observables to toggle the sidebar from any part of your application and track the active links accordingly. With this method, you can utilize the
**
catchall route independently of the router configuration.
Please note that the examples provided assume no prior knowledge of your specific business logic.
If your sidebar is data-driven, the implementation may vary. For instance, if your sidebar items have unique identifiers, you can dynamically set active links based on the URL parameters. In such cases, handling routes like
/topic/:topicId/subtopic/:subtopicId
becomes simplified by leveraging router events and matching IDs for seamless toggling.
Approach #1
The following treeview links demonstrate navigation behavior and respective link activation:
/link1
/link1/sublink1
/link1/sublink1/sub2link1
/link1/sublink2
/link2
/link3
Sample sidebar structure:
<ul>
<li>
<a [routerLink]="['/link1']" [routerLinkActive]="'active'">Link1</a>
<ul>
<li>
<a [routerLink]="['/link1/sublink1']" [routerLinkActive]="'active'">Sublink1</a>
<ul>
<li>
<a [routerLink]="['/link1/sublink1/sub2link1']" [routerLinkActive]="'active'">Sub2link1</a>
</li>
</ul>
</li>
<li>
<a [routerLink]="['/link1/sublink2']" [routerLinkActive]="'active'">Sublink2</a>
</li>
</ul>
</li>
<li>
<a [routerLink]="['/link2']" [routerLinkActive]="'active'">Link2</a>
</li>
<li>
<a [routerLink]="['/link3']" [routerLinkActive]="'active'">Link3</a>
</li>
</ul>
Approach #2
This method involves triggering a function within your component or service to establish and update a particular state before navigating. By monitoring these changes through an Observable, the sidebar can dynamically adjust active links based on these interactions.
Here's a conceptual example:
Template:
<ul>
<li>
<a (click)="toggleSidebar('link1')" [class.active]="activeLink === 'link1'">Link1</a>
</li>
<li>
<a (click)="toggleSidebar('link2')" [class.active]="activeLink === 'link2'">Link2</a>
<ul>
<li>
<a (click)="toggleSidebar('link2/sublink1')" [class.active]="activeLink === 'link2/sublink1'">Link2 Sublink1</a>
</li>
</ul>
</li>
</ul>
Component:
@Component({...})
export class MyComponent implements OnInit {
activeLink: string;
constructor(private sidebarService: SideberService) {}
ngOnInit() {
this.sidebarService.activeLink$.subscribe((activeLink: string) => {
this.activeLink = activeLink;
}));
}
toggleSidebar(activeLink: string) {
this.sidebarService.activeLink.next(activeLink);
}
}
Service:
@Injectable()
export class SidebarService {
activeLink: ReplaySubject<string> = new ReplaySubject();
activeLink$: Observable<string> = this.activeLink.asObservable();
}
By emitting values into sidebarService.activeLink
, the sidebar component can react to these changes and reflect them as active links in the user interface.
If you wish to initialize the sidebar with a default active link, consider using a BehaviorSubject
with a predefined value like link1
. Here's how it can be implemented:
@Injectable()
export class SidebarService {
activeLink: BehaviorSubject<string> = new BehaviorSubject('link1');
activeLink$: Observable<string> = this.activeLink.asObservable();
}
This way, upon loading the page, the sidebar will display link1
as the default active link due to the initial stream value.