Components: md-tab-nav-bar does not properly display active when child/relative routes are involved (removing the md- directives fix this)

Created on 21 Jul 2017  路  6Comments  路  Source: angular/components

Bug, feature request, or proposal:

Bug

What is the expected behavior?

Any active routerLinks with the md-tab-link directive should show the material design active styling

What is the current behavior?

Paths with children and or relative paths seem to break the md-tab-nav-bar active styling (the individual tabs do not show the active styling when the corresponding route is active).

What are the steps to reproduce?

I created a repo reproducing the problem at: https://github.com/danwulff/md-tab-nav-bar-error-with-children

Steps to reproduce:

  • In a terminal $ git clone https://github.com/danwulff/md-tab-nav-bar-error-with-children && cd md-tab-nav-bar-error-with-children && npm install && ng serve
  • browser to http://localhost:4200/
  • click 'sub route'
  • click through the tabs to see that the first 3 don't work

The markup of the tabs is found within sub.component.html

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

@angular/cdk, @angular/material: 2.0.0-beta.8
Tested in Google Chrome 59

Most helpful comment

Just took a look and there are two issues with your markup:

  1. md-tab-nav requires that only one tab is considered active at a time. This means that duplicating tabs for sub/ (or "one") will behave unexpectedly. So the first step is to be sure to only use a single tab for any unique route

  2. In your master branch, you are redefining #rla for each tab. AFAIK the scope of this reference is template-wide, so really you're just overwriting it 3 times. Opt for using a unique template reference name for each tab or use *ngFor like below,

<nav md-tab-nav-bar>
  <a md-tab-link *ngFor="let tab of tabs"
    [routerLink]="[tab.path]"
    routerLinkActive
    #rla="routerLinkActive"
    [routerLinkActiveOptions]="{exact: true}"
    [active]="rla.isActive">
    {{ tab.label }}
  </a>
</nav>
  tabs = [
    { path: './', label: 'one' },
    { path: 'two/123', label: 'two with param' },
    { path: 'two', label: 'two' }
  ]

I hope this helps!

All 6 comments

Without diving into your repo, did you look at using an exact route match?

https://angular.io/api/router/RouterLinkActive#routerLinkActiveOptions

<div routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">
  <a routerLink="/user/jim">Jim</a>
  <a routerLink="/user/bob">Bob</a>
</div>

I made a branch showing that routerLinkActive works when stripping the material stuff out: https://github.com/danwulff/md-tab-nav-bar-error-with-children/tree/pure-routerLink
$ git checkout pure-routerLink

Since I'm unsure, I'll leave this open until someone finds an issue to associate in @angular/router.

After poking around a bit more I think this may have to do with the routerLinkActive directive in the router module: https://angular.io/api/router/RouterLinkActive~~

I'm unsure if it currently supports relative paths. I'll do a little more research when I have time, which may be a while (who moves apartments in July blegh).

Just took a look and there are two issues with your markup:

  1. md-tab-nav requires that only one tab is considered active at a time. This means that duplicating tabs for sub/ (or "one") will behave unexpectedly. So the first step is to be sure to only use a single tab for any unique route

  2. In your master branch, you are redefining #rla for each tab. AFAIK the scope of this reference is template-wide, so really you're just overwriting it 3 times. Opt for using a unique template reference name for each tab or use *ngFor like below,

<nav md-tab-nav-bar>
  <a md-tab-link *ngFor="let tab of tabs"
    [routerLink]="[tab.path]"
    routerLinkActive
    #rla="routerLinkActive"
    [routerLinkActiveOptions]="{exact: true}"
    [active]="rla.isActive">
    {{ tab.label }}
  </a>
</nav>
  tabs = [
    { path: './', label: 'one' },
    { path: 'two/123', label: 'two with param' },
    { path: 'two', label: 'two' }
  ]

I hope this helps!

Closing based on @willshowell's observations

Personally, using @willshowell's answer gives me errors.

ERROR Error: "Uncaught (in promise): Error: Template parse errors:
Can't bind to 'active' since it isn't a known property of 'a'. ("nk]="[tab.path]" routerLinkActive #rla="routerLinkActive" [routerLinkActiveOptions]="{exact: true}" [ERROR ->][active]="rla.isActive">
    {{ tab.label }}
  </a>
"): ng:///ComplaintDetailsModule/ComplaintDetailsComponent.html@1:152

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings