Angular 2 exact RouterLinkActive including fragments?

When using routerLink and routerLinkActive to apply CSS to the navigation bar, I would also like to include fragment information so that the links are unique to sections on the home page.

I tried using [routerLinkActiveOptions]="{ exact: true }" without any luck.

Relevant part of the navigation bar code:

  <li routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }"> <a routerLink="/sitio" fragment="inicio">Inicio</a> </li> <li routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }"> <a routerLink="/sitio" fragment="invierte">Invierte</a> </li> <li routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }"> <a routerLink="/sitio" fragment="contacto">Contacto</a> </li> 

The three different URLs above are as follows:

  • /sitio#inicio
  • /sitio#invierte
  • /sitio#contacto

But each time you press any of them, they are all marked as active (since they correspond to the information routerLink="/sitio" and fragment=* ), which are not included in the check. This leads to the fact that the navigation bar looks like this: by clicking on any of them:

enter image description here

Any ideas on how to do this?

+12
source share
4 answers

There is an open issue to support https://github.com/angular/angular/issues/13205

routerLinkActive is a simple directive. You could create a clone yourself with this advanced functionality.

+4
source

I just thought that I would set it, as I solved it, if someone encounters the same problem: track the current section of the site and use the class binding through the function in the component instead of routerLinkActive .

Links in the template will become:

 <li [class.active]="isSectionActive('inicio')"> <a routerLink="/sitio" fragment="inicio">Inicio</a> </li> <li [class.active]="isSectionActive('invierte')"> <a routerLink="/sitio" fragment="invierte">Invierte</a> </li> <li [class.active]="isSectionActive('contacto')"> <a routerLink="/sitio" fragment="contacto">Contacto</a> </li> 

Note the lack of using routerLinkActive and the use of class binding [class.active]=isSectionActive('<name-of-section>') .

The code that tracks the section we are in and determines whether to apply the CSS class in the template:

 import { Router, NavigationEnd } from '@angular/router'; // Class signature... { private activeSiteSection: string; constructor( private router: Router, private sessionService: SessionService ) { router.events.subscribe((event) => { if(event instanceof NavigationEnd ) { this.SiteURLActiveCheck(event); } }); } private SiteURLActiveCheck(event: NavigationEnd): void { if (event.url.indexOf('#inicio') !== -1) { this.activeSiteSection = 'inicio'; } else if (event.url.indexOf('#invierte') !== -1) { this.activeSiteSection = 'invierte'; } else if (event.url.indexOf('#contacto') !== -1) { this.activeSiteSection = 'contacto'; } else { this.activeSiteSection = ''; } } private isSectionActive(section: string): boolean { return section === this.activeSiteSection; } } 

Probably too much, but I would rather go this route than change the source of Angular 2. :)

+7
source

Make Omar Trejo's approach easier. Instead of subscribing to a Route, I updated isSectionActive to look at location.href to make it work.

 private isSectionActive(section: string): boolean { return location.href.indexOf(section) !== -1; } 
0
source

I struggle [routerLinkActiveOptions]="{ exact: true }" to work with [routerLinkActiveOptions]="{ exact: true }" even on Angular 7.

So, I used the following trick to solve this problem. Answer ActivatedRoute .

in Component .

 class ComponentClass{ public activeFragment = this.route.fragment.pipe(share()); constructor(public route: ActivatedRoute){} } 

In template use this as follows.

 <li [class.active]="(activeFragment | async)==='inicio'"> <a routerLink="/sitio" fragment="inicio">Inicio</a> </li> <li [class.active]="(activeFragment | async)==='invierte'"> <a routerLink="/sitio" fragment="invierte">Invierte</a> </li> <li [class.active]="(activeFragment | async)==='contacto'"> <a routerLink="/sitio" fragment="contacto">Contacto</a> </li 

I'm not sure about the share operator here. I did not look at this if its multicast by default. Let me know if you have an answer to this question.

0
source

Source: https://habr.com/ru/post/1013631/


All Articles