Search code examples
angularroutesangular2-routingrouter

Angular 2 Router link active with two links activating


I have a project with the following routes:

{ path: '', component: GamesListingComponent },

    { path: 'inicio', component: HomeComponent },

    { path: 'listar',
        children: [
            { path: '', component: HomeComponent },
            { path: 'fabricantes', component: ManufacturesListingComponent },
            { path: 'plataformas', component: PlatformsListingComponent },
            { path: 'usuarios', component: UsersListingComponent },
            { path: 'jogos', component: GamesListingComponent },
            { path: '**', component: HomeComponent }
        ]
    },

    { path: 'cadastrar',
        children: [
            { path: '', component: HomeComponent },
            { path: 'fabricantes', component: ManufacturesRegisterComponent },
            { path: 'plataformas', component: PlatformsRegisterComponent },
            { path: 'usuarios', component: UsersRegisterComponent },
            { path: 'jogos', component: GamesRegisterComponent },
            { path: '**', component: HomeComponent }
        ]
    },

    { path: '**', component: GamesListingComponent }

And I would like the routerLinkActive to be enabled only by the name of the child routes, for example:

When accessing "/listar/jogos" and "/cadastrar/jogos", wanted to be accessed these two routes the same routerLinkActive was active.

header.html

<div class="jumbotron">
    <p class="text-center title"><a [routerLink]="['/inicio']">Lightning Games</a></p>
    <p class="text-center">A sua loja de jogos desde o seu primeiro dia</p>
</div>
<nav class="navbar navbar-toggleable-md navbar-inverse bg-inverse">
    <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarText">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item" [routerLinkActive]="['active']">
                <a class="nav-link" [routerLink]="['/inicio']">Início <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item" [routerLinkActive]="['active']">
                <a class="nav-link" [routerLink]="['/listar', 'plataformas']">Plataformas</a>
            </li>
            <li class="nav-item" [routerLinkActive]="['active']">
                <a class="nav-link" [routerLink]="['/listar', 'fabricantes']">Fabricantes</a>
            </li>
            <li class="nav-item" [routerLinkActive]="['active']">
                <a class="nav-link" [routerLink]="['/listar', 'usuarios']">Usuários</a>
            </li>
            <li class="nav-item" [routerLinkActive]="['active']">
                <a class="nav-link" [routerLink]="['/listar', 'jogos']">Jogos</a>
            </li>
        </ul>
    </div>
</nav>

Solution

    1. If you want your route to be active for ONE EXACT ROUTE

    Adding [routerLinkActiveOptions]="{exact:true}" will make the active class only apply to exact route matches.

    If that is what you want, then update your <li> tags as follows:

    <li class="nav-item" [routerLinkActive]="['active']" [routerLinkActiveOptions]="{exact:true}">
       <a class="nav-link" [routerLink]="['/inicio']">Início <span class="sr-only">(current)</span></a>
    </li>
    
    1. If you want to have your route link active for MULTIPLE SIMILAR ROUTES

    Look at this Plunkr code that I have modified from one of the official Angular routing examples. https://plnkr.co/edit/wWyVfxDHbSA8tYcpsNsF?p=preview

    Take note of two things:

    • In app-routing.module.ts you will see that there are two similar routes:

    { path: 'heroes/:id', component: HeroDetailComponent }, { path: 'heroes', component: HeroesComponent }

    • In app.component.ts (in the embedded template code) you will see that their is a route:

    <routerLink="/heroes" routerLinkActive="active">Heroes</a>

    This route matches BOTH of the paths set in app-routing.module.ts - this means that it will have the active class applied for any route that starts with /heroes

    UPDATE:

    In your example, you can do this by changing your routing to the following:

    app.routes.ts

    const appRoutes: Routes = [
    
      { path: '', component: GamesListingComponent },
    
      { path: 'inicio', component: HomeComponent },
    
      { path: '', component: HomeComponent },
    
      { path: 'jogos', component: GamesListingComponent },
      { path: 'fabricantes', component: ManufacturesListingComponent },
      { path: 'plataformas', component: PlatformsListingComponent },
      { path: 'usuarios', component: UsersListingComponent },
    
      { path: 'jogos/cadastrar', component: GamesRegisterComponent },
      { path: 'fabricantes/cadastrar', component: ManufacturesRegisterComponent },
      { path: 'plataformas/cadastrar', component: PlatformsRegisterComponent },
      { path: 'usuarios/cadastrar', component: UsersRegisterComponent },
    
      { path: '**', component: GamesListingComponent }
    
    ];
    
    export const routing = RouterModule.forRoot(appRoutes);`
    

    header.component.html

            <li class="nav-item" [routerLinkActive]="['active']">
                <a class="nav-link" [routerLink]="['/inicio']">Início <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item" [routerLinkActive]="['active']">
                <a class="nav-link" [routerLink]="['/plataformas']">Plataformas</a>
            </li>
            <li class="nav-item" [routerLinkActive]="['active']">
                <a class="nav-link" [routerLink]="['/fabricantes']">Fabricantes</a>
            </li>
            <li class="nav-item" [routerLinkActive]="['active']">
                <a class="nav-link" [routerLink]="['/usuarios']">Usuários</a>
            </li>
            <li class="nav-item" [routerLinkActive]="['active']" >
                <a class="nav-link" [routerLink]="['/jogos']">Jogos</a>
            </li>
    

    xxx-listing.component.html

    <a [routerLink]="['/jogos/cadastrar']" class="btn btn-primary">
      Novo Jogo
    </a>