-->

Angular 6 Material: mat-tab-link be selected by un

2020-08-15 06:32发布

问题:

I have a mat-tab-nav-bar navigation bar for my website, but the mat-tab-link blue underlining bar won't chase the active button. It just stays at the first button, and doesn't move. The buttons do turn into active state though in the sense that the background color changes, and they route well to their corresponding pages.

Here's the app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  navLinks = [
    { path: '', label: 'The Problem' },
    { path: 'the-solution', label: 'The Solution' },
    { path: 'the-game', label: 'The Game' },
    { path: 'probability-calculator', label: 'Probability calculator' },
  ];
}

And here's the app.component.html:

<nav mat-tab-nav-bar>
  <a mat-tab-link
     *ngFor="let link of navLinks"
     [routerLink]="link.path"
     routerLinkActive #rla="routerLinkActive"
     [active]="rla.isActive">
    {{link.label}}
  </a>
</nav>

<router-outlet></router-outlet>

Here is the app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { AppRoutingModule } from './app-routing.module';

import { AppComponent } from './app.component';
import { TheProblemComponent } from './the-problem/the-problem.component';
import { TheSolutionComponent } from './the-solution/the-solution.component';
import { ProbabilityCalculatorComponent } from './probability-calculator/probability-calculator.component';
import { TheGameComponent } from './the-game/the-game.component';

@NgModule({
  declarations: [
    AppComponent,
    TheProblemComponent,
    TheSolutionComponent,
    ProbabilityCalculatorComponent,
    TheGameComponent
  ],
  imports: [
    AppRoutingModule,
    BrowserModule,
    BrowserAnimationsModule,
    MatTabsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

What am I missing? Thank you!

EDIT

I edited the app.component.html like this to find out some more about the link "active" state:

<nav mat-tab-nav-bar>
  <a mat-tab-link
     *ngFor="let link of navLinks"
     [routerLink]="link.path"
     routerLinkActive #rla="routerLinkActive"
     [active]="rla.isActive">
    {{link.label}}
    <div style="color: red; margin-left: 10px;">
        <span *ngIf="rla.isActive"> Is active!</span>
        <span *ngIf="!rla.isActive"> Is not active...</span>
    </div>
  </a>
</nav>

<router-outlet></router-outlet>

As it turns out, the first link in the menu always remains active (rla.isActive) - also when I'm navigating to other pages. All other links turn off their active state just fine, and only get activated when they are navigated to. How do I turn off the active state of the first link when navigating to other links?

EDIT 2

Adding app-routing.module.ts code:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { TheProblemComponent } from './the-problem/the-problem.component';
import { TheSolutionComponent } from './the-solution/the-solution.component';
import { TheGameComponent } from './the-game/the-game.component';
import { ProbabilityCalculatorComponent } from './probability-calculator/probability-calculator.component';

const routes: Routes = [
    { path: '', component: TheProblemComponent },
    { path: 'the-solution', component: TheSolutionComponent },
    { path: 'the-game', component: TheGameComponent },
    { path: 'probability-calculator', component: ProbabilityCalculatorComponent }
];


@NgModule({
  imports: [ RouterModule.forRoot(routes) ],
  exports: [ RouterModule ]
})
export class AppRoutingModule { }

回答1:

It doesn't work for you because every has the same #rla variable

You can do it this way:

<nav mat-tab-nav-bar>
  <a mat-tab-link
     *ngFor="let link of navLinks"
     [routerLink]="link.path"
     routerLinkActive #rla="routerLinkActive"
     [active]="link.isActive">
    {{link.label}}
  </a>
</nav>

<router-outlet></router-outlet>

or with {exact:true}

<nav mat-tab-nav-bar>
  <a mat-tab-link
     *ngFor="let link of navLinks"
     [routerLink]="link.path"
     routerLinkActive #rla="routerLinkActive"
     [routerLinkActiveOptions]="{exact:true}"
     [active]="rla.isActive">
    {{link.label}}
  </a>
</nav>

<router-outlet></router-outlet>



回答2:

You're missing a / before the link:

<nav mat-tab-nav-bar>
  <a mat-tab-link
     *ngFor="let link of navLinks"
     [routerLink]="['/'+link.path]"
     routerLinkActive #rla="routerLinkActive"
     [active]="rla.isActive">
    {{link.label}}
  </a>
</nav>

<router-outlet></router-outlet>

EDIT: The right way here is to set a non-empty path for all routes. You can then use a wildcard with a redirect.

const APP_ROUTES: Route[] = [
  { path: 'path-1', component: OneComponent },
  { path: 'path-2', component: TwoComponent },
  { path: 'path-3', component: ThreeComponent },
  { path: '**', redirectTo: 'path-1' },
]


回答3:

Using different local variables(#rla1, #rla2) worked for me, as i was not using *ngFor:

<nav mat-tab-nav-bar>
    <a mat-tab-link
       [routerLink]="['/home/homepage/dashboard/']"
       routerLinkActive #rla1="routerLinkActive"
       [active]="rla1.isActive">Dashboard
    </a>
    <a mat-tab-link
       [routerLink]="['/home/homepage/reports/']"
       routerLinkActive #rla2="routerLinkActive"
       [active]="rla2.isActive">Reports
    </a>
</nav>


回答4:

You need to add [routerLinkActiveOptions]="{exact:true}" to the a tag. It becomes

<nav mat-tab-nav-bar>
  <a mat-tab-link
     *ngFor="let link of navLinks"
     [routerLink]="link.path"
     routerLinkActive #rla="routerLinkActive"
     [routerLinkActiveOptions]="{exact:true}"
     [active]="rla.isActive">
    {{link.label}}
    <div style="color: red; margin-left: 10px;">
        <span *ngIf="rla.isActive"> Is active!</span>
        <span *ngIf="!rla.isActive"> Is not active...</span>
    </div>
  </a>
</nav>

<router-outlet></router-outlet>


回答5:

You can simply follow below code.active is simply bootstrap class.

<nav mat-tab-nav-bar>
  <a mat-tab-link
  *ngFor="let link of navLinks"
  [routerLink]="['/'+link.path]"
  routerLinkActive="active">
  {{link.label}}
  </a>
</nav>

OR you can do like this below instead of using material design. kindly notice routerLinkActiveOptions is used.

<ul class="nav nav-tabs">
    <li role="presentation"
        routerLinkActive="active"
        [routerLinkActiveOptions]="{exact: true}">
      <a routerLink="/">The Problem</a>
    </li>
    <li role="presentation"
        routerLinkActive="active">
      <a routerLink="/the-solution">The Solution</a>
    </li>
    <li role="presentation"
        routerLinkActive="active">
      <a [routerLink]="/the-game">The Game</a>
    </li>
    ....
    ....
 </ul>