ПРИМЕЧАНИЕ. Здесь много разных ответов, и большинство из них были действительны в тот или иной момент. Дело в том, что то, что работает, несколько раз менялось, когда команда Angular меняла свой маршрутизатор. Версия Router 3.0, которая в конечном итоге станет маршрутизатором в Angular, ломает многие из этих решений, но предлагает очень простое собственное решение. Начиная с RC.3, предпочтительным решением является использование [routerLinkActive], как показано в этом ответе.

В приложении Angular (текущем в версии 2.0.0-бета.0, когда я пишу это), как вы определяете, какой сейчас активный маршрут?

Я работаю над приложением, которое использует Bootstrap 4, и мне нужен способ пометить навигационные ссылки / кнопки как активные, когда их связанный компонент отображается в теге <router-output>.

Я понимаю, что могу поддерживать состояние самостоятельно, когда нажата одна из кнопок, но это не будет охватывать случай наличия нескольких путей в одном маршруте (скажем, главное навигационное меню, а также локальное меню в главном компоненте). ) .

Любые предложения или ссылки будут оценены. Спасибо.

334
Michael Oryl 17 Дек 2015 в 01:37

28 ответов

Лучший ответ

С новым Angular router вы можете добавить атрибут [routerLinkActive]="['your-class-name']" для всех ваших ссылок:

<a [routerLink]="['/home']" [routerLinkActive]="['is-active']">Home</a>

Или упрощенный формат без массива, если нужен только один класс:

<a [routerLink]="['/home']" [routerLinkActive]="'is-active'">Home</a>

Или еще более простой формат, если нужен только один класс:

<a [routerLink]="['/home']" routerLinkActive="is-active">Home</a>

См. X {}} } директива для получения дополнительной информации. (Я в основном понял это методом проб и ошибок.)

ОБНОВЛЕНИЕ: более качественную документацию для директивы routerLinkActive теперь можно найти здесь. (Спасибо @Victor Hugo Arango A. в комментариях ниже.)

345
random_user_name 13 Авг 2019 в 23:00

Я искал способ использовать навигацию в стиле Bootstrap в Twitter с Angular2, но у меня возникли проблемы с применением класса active к родительскому элементу выбранной ссылки. Обнаружил, что решение @ alex-correia-santos работает отлично!

Компонент, содержащий ваши вкладки, должен импортировать маршрутизатор и определить его в своем конструкторе, прежде чем вы сможете выполнить необходимые вызовы.

Вот упрощенная версия моей реализации ...

import {Component} from 'angular2/core';
import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {HomeComponent} from './home.component';
import {LoginComponent} from './login.component';
import {FeedComponent} from './feed.component';

@Component({
  selector: 'my-app',
  template: `
    <ul class="nav nav-tabs">
      <li [class.active]="_r.isRouteActive(_r.generate(['Home']))">
        <a [routerLink]="['Home']">Home</a>
      </li>
      <li [class.active]="_r.isRouteActive(_r.generate(['Login']))">
        <a [routerLink]="['Login']">Sign In</a>
      </li>
      <li [class.active]="_r.isRouteActive(_r.generate(['Feed']))">
        <a [routerLink]="['Feed']">Feed</a>
      </li>
    </ul>`,
  styleUrls: ['app/app.component.css'],
  directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
  { path:'/', component:HomeComponent, name:'Home', useAsDefault:true },
  { path:'/login', component:LoginComponent, name:'Login' },
  { path:'/feed', component:FeedComponent, name:'Feed' }
])
export class AppComponent {
  title = 'My App';
  constructor( private _r:Router ){}
}
1
Ben Thielker 13 Апр 2016 в 18:25

Ниже приведены ответы на этот вопрос для всех версий Angular 2 RC, выпущенных до даты:

RC4 и RC3 .

Для применения класса к ссылке или предку ссылки:

<li routerLinkActive="active"><a [routerLink]="['/home']">Home</a></li>

/ home должен быть URL-адресом, а не именем маршрута, поскольку свойство имени больше не существует в объекте маршрута с версии Router v3.

Подробнее о директиве routerLinkActive можно узнать по этой ссылке.

Для применения класса к любому div на основе текущего маршрута:

  • Внедрить маршрутизатор в конструктор компонента.
  • Пользователь router.url для сравнения.

Например

<nav [class.transparent]="router.url==('/home')">
</nav>

RC2 и RC1 .

Используйте комбинацию router.isRouteActive и class. *. например, применить активный класс на основе Home Route.

Имя и URL могут быть переданы в router.generate.

 <li [class.active]="router.isRouteActive(router.generate(['Home']))">
    <a [routerLink]="['Home']" >Home</a>
</li>
4
Inderdeep Singh 15 Июл 2016 в 10:15

Ниже приведен метод использования RouteData для стилизации элементов menuBar в зависимости от текущего маршрута:

RouteConfig включает данные с вкладки (текущий маршрут):

@RouteConfig([
  {
    path: '/home',    name: 'Home',    component: HomeComponent,
    data: {activeTab: 'home'},  useAsDefault: true
  }, {
    path: '/jobs',    name: 'Jobs',    data: {activeTab: 'jobs'},
    component: JobsComponent
  }
])

Кусок макета:

  <li role="presentation" [ngClass]="{active: isActive('home')}">
    <a [routerLink]="['Home']">Home</a>
  </li>
  <li role="presentation" [ngClass]="{active: isActive('jobs')}">
    <a [routerLink]="['Jobs']">Jobs</a>
  </li>

Учебный класс:

export class MainMenuComponent {
  router: Router;

  constructor(data: Router) {
    this.router = data;
  }

  isActive(tab): boolean {
    if (this.router.currentInstruction && this.router.currentInstruction.component.routeData) {
      return tab == this.router.currentInstruction.component.routeData.data['activeTab'];
    }
    return false;
  }
}
7
Ivan 15 Апр 2016 в 09:07

Небольшое улучшение ответа @ alex-correia-santos на основе https://github.com / угловой / угловой / тянуть / 6407 # issuecomment - 190179875

import {Router, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
// ...
export class App {
  constructor(private router: Router) {
  }

  // ...

  isActive(instruction: any[]): boolean {
    return this.router.isRouteActive(this.router.generate(instruction));
  }
} 

И используйте это так:

<ul class="nav navbar-nav">
    <li [class.active]="isActive(['Home'])">
        <a [routerLink]="['Home']">Home</a>
    </li>
    <li [class.active]="isActive(['About'])">
        <a [routerLink]="['About']">About</a>
    </li>
</ul>
33
tomaszbak 7 Июн 2016 в 20:52

А в последней версии angular вы можете просто сделать проверку router.isActive(routeNameAsString). Например, см. Пример ниже:

 <div class="collapse navbar-collapse" id="navbarNav">
    <ul class="navbar-nav">
      <li class="nav-item" [class.active] = "router.isActive('/dashboard')">
        <a class="nav-link" href="#">داشبورد <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item" [class.active] = "router.isActive(route.path)" *ngFor="let route of (routes$ | async)">
        <a class="nav-link" href="javascript:void(0)" *ngIf="route.childRoutes && route.childRoutes.length > 0"
          [matMenuTriggerFor]="menu">{{route.name}}</a>
        <a class="nav-link" href="{{route.path}}"
          *ngIf="!route.childRoutes || route.childRoutes.length === 0">{{route.name}}</a>
        <mat-menu #menu="matMenu">
          <span *ngIf="route.childRoutes && route.childRoutes.length > 0">
            <a *ngFor="let child of route.childRoutes" class="nav-link" href="{{route.path + child.path}}"
              mat-menu-item>{{child.name}}</a>
          </span>
        </mat-menu>
      </li>
    </ul>
    <span class="navbar-text mr-auto">
      <small>سلام</small> {{ (currentUser$ | async) ? (currentUser$ | async).firstName : 'کاربر' }}
      {{ (currentUser$ | async) ? (currentUser$ | async).lastName : 'میهمان' }}
    </span>
  </div>

И убедитесь, что вы не забыли ввести роутер в свой компонент.

2
ConductedClever 19 Июл 2019 в 09:18

Как вы определяете, какой сейчас активный маршрут?

ОБНОВЛЕНИЕ: обновлено в соответствии с Angular2.4.x

constructor(route: ActivatedRoute) {
   route.snapshot.params; // active route's params

   route.snapshot.data; // active route's resolved data

   route.snapshot.component; // active route's component

   route.snapshot.queryParams // The query parameters shared by all the routes
}

узнать больше...

17
Ankit Singh 27 Дек 2016 в 10:09

В 2020 году, если вы хотите установить активный класс для элемента, который не имеет [routerLink] - вы можете просто сделать:

<a
  (click)="bookmarks()"
  [class.active]="router.isActive('/string/path/'+you+'/need', false)" // <== you need this one. second argument 'false' - exact: true/false
  routerLinkActive="active"
  [routerLinkActiveOptions]="{ exact: true }"
>
  bookmarks
</a>

3
Kurkov Igor 29 Янв 2020 в 22:33

Как упомянуто в одном из комментариев принятого ответа, директива routerLinkActive может также применяться к контейнеру фактического тега <a>.

Например, с вкладками Twitter Bootstrap , где активный класс должен применяться к тегу <li>, содержащему ссылку:

<ul class="nav nav-tabs">
    <li role="presentation" routerLinkActive="active">
        <a routerLink="./location">Location</a>
    </li>
    <li role="presentation" routerLinkActive="active">
        <a routerLink="./execution">Execution</a>
    </li>
</ul>

Довольно аккуратно! Я предполагаю, что директива проверяет содержимое тега и ищет тег <a> с директивой routerLink.

3
Pierre Henry 3 Ноя 2016 в 15:24

Экземпляр класса Router на самом деле является Observable, и он возвращает текущий путь каждый раз, когда изменяется. Вот как я это делаю:

export class AppComponent implements OnInit { 

currentUrl : string;

constructor(private _router : Router){
    this.currentUrl = ''
}

ngOnInit() {
    this._router.subscribe(
        currentUrl => this.currentUrl = currentUrl,
        error => console.log(error)
    );
}

isCurrentRoute(route : string) : boolean {
    return this.currentUrl === route;
 } 
}

А потом в моем HTML:

<a [routerLink]="['Contact']" class="item" [class.active]="isCurrentRoute('contact')">Contact</a>
3
Anees Dhansey 15 Май 2016 в 17:50

Для Angular версии 4+ вам не нужно использовать какое-либо сложное решение. Вы можете просто использовать [routerLinkActive]="'is-active'".

Для примера с загрузочной ссылкой 4:

    <ul class="navbar-nav mr-auto">
      <li class="nav-item" routerLinkActive="active">
        <a class="nav-link" routerLink="/home">Home</a>
      </li>
      <li class="nav-item" routerLinkActive="active">
        <a class="nav-link" routerLink="/about-us">About Us</a>
      </li>
      <li class="nav-item" routerLinkActive="active">
        <a class="nav-link " routerLink="/contact-us">Contact</a>
      </li>
    </ul>
4
Michael Oryl 12 Окт 2017 в 17:26

Использование routerLinkActive хорошо в простых случаях, когда есть ссылка, и вы хотите применить некоторые классы. Но в более сложных случаях, когда у вас может не быть routerLink или вам нужно что-то еще, вы можете создать и использовать pipe :

@Pipe({
    name: "isRouteActive",
    pure: false
})
export class IsRouteActivePipe implements PipeTransform {

    constructor(private router: Router,
                private activatedRoute: ActivatedRoute) {
    }

    transform(route: any[], options?: { queryParams?: any[], fragment?: any, exact?: boolean }) {
        if (!options) options = {};
        if (options.exact === undefined) options.exact = true;

        const currentUrlTree = this.router.parseUrl(this.router.url);
        const urlTree = this.router.createUrlTree(route, {
            relativeTo: this.activatedRoute,
            queryParams: options.queryParams,
            fragment: options.fragment
        });
        return containsTree(currentUrlTree, urlTree, options.exact);
    }
}

Тогда:

<div *ngIf="['/some-route'] | isRouteActive">...</div>

И не забудьте включить трубу в зависимости от каналов;)

4
pleerock 16 Июл 2016 в 18:42

В Angular2 RC2 вы можете использовать эту простую реализацию

<a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>

Это добавит класс active к элементу с соответствующим URL, узнайте больше об этом здесь

4
Khaled Al-Ansari 10 Июл 2016 в 09:44

Еще один обходной путь. Гораздо проще в Angular Router V3 Alpha. вводя маршрутизатор

import {Router} from "@angular/router";

export class AppComponent{

    constructor(private router : Router){}

    routeIsActive(routePath: string) {
        return this.router.url == routePath;
    }
}

Применение

<div *ngIf="routeIsActive('/')"> My content </div>
4
shakee93 25 Июн 2016 в 11:17

Router в Angular 2 RC больше не определяет isRouteActive и generate методы.

urlTree - возвращает текущее дерево URL.

createUrlTree(commands: any[], segment?: RouteSegment) - применяет массив команд к текущему дереву URL и создает новое дерево URL.

Попробуйте следовать

<li 
[class.active]=
"router.urlTree.contains(router.createUrlTree(['/SignIn', this.routeSegment]))">

уведомление, routeSegment : RouteSegment должен быть вставлен в конструктор компонента.

6
tchelidze 27 Май 2016 в 12:45

Прямо сейчас я использую RC.4 с начальной загрузкой 4, и этот работает идеально для меня:

 <li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact:
true}">
    <a class="nav-link" [routerLink]="['']">Home</a>
</li>

Это будет работать для URL: / home

10
Artem Zinoviev 10 Авг 2016 в 12:28

Вы можете проверить текущий маршрут, вставив объект Location в контроллер и проверив path(), например так:

class MyController {
    constructor(private location:Location) {}

    ...  location.path(); ...
}

Вы должны будете убедиться, что импортировали это сначала:

import {Location} from "angular2/router";

Затем вы можете использовать регулярное выражение для сопоставления с путем, который возвращается, чтобы увидеть, какой маршрут активен. Обратите внимание, что класс Location возвращает нормализованный путь независимо от того, какой LocationStrategy вы используете. Таким образом, даже если вы используете HashLocationStragegy, возвращаемые пути все равно будут иметь вид /foo/bar не #/foo/bar

30
Mark Rajcok 5 Янв 2016 в 02:55

Я решил проблему, с которой столкнулся в этом ссылка и я выясняю, что есть простое решение для вашего вопроса. Вы можете использовать router-link-active вместо этого в своих стилях.

@Component({
   styles: [`.router-link-active { background-color: red; }`]
})
export class NavComponent {
}
35
Community 23 Май 2017 в 12:18

Начать с импорта RouterLinkActive в ваши .ts

импортировать {RouterLinkActive} из '@ angular / router';

Теперь используйте RouterLinkActive в вашем HTML

<span class="" routerLink ="/some_path" routerLinkActive="class_Name">Value</span></a>

Предоставить некоторую CSS для класса "class_Name", так как, когда эта ссылка будет активна / нажата, вы найдете этот класс на промежутке во время проверки.

0
T. Shashwat 15 Окт 2018 в 06:24

Просто подумал, что я бы добавил в пример, который не использует машинописный текст:

<input type="hidden" [routerLink]="'home'" routerLinkActive #home="routerLinkActive" />
<section *ngIf="home.isActive"></section>

Переменная routerLinkActive связана с переменной шаблона и затем используется повторно при необходимости. К сожалению, единственное предостережение в том, что вы не можете иметь все это в элементе <section>, поскольку #home необходимо разрешить до , чтобы синтаксический анализатор нажал <section>.

6
Zze 21 Фев 2018 в 10:03

Вот полный пример добавления активного стиля маршрута в угловой версии 2.0.0-rc.1, которая учитывает нулевые корневые пути (например, path: '/')

app.component.ts -> Маршруты

import { Component, OnInit } from '@angular/core';
import { Routes, Router, ROUTER_DIRECTIVES } from '@angular/router';
import { LoginPage, AddCandidatePage } from './export';
import {UserService} from './SERVICES/user.service';

@Component({
  moduleId: 'app/',
  selector: 'my-app',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css'],
  providers: [UserService],
  directives: [ROUTER_DIRECTIVES]
})

@Routes([
  { path: '/', component: AddCandidatePage },
  { path: 'Login', component: LoginPage }
])
export class AppComponent  { //implements OnInit

  constructor(private router: Router){}

  routeIsActive(routePath: string) {
     let currentRoute = this.router.urlTree.firstChild(this.router.urlTree.root);
     // e.g. 'Login' or null if route is '/'
     let segment = currentRoute == null ? '/' : currentRoute.segment;
     return  segment == routePath;
  }
}

app.component.html

<ul>
  <li [class.active]="routeIsActive('Login')"><a [routerLink]="['Login']" >Login</a></li>
  <li [class.active]="routeIsActive('/')"><a [routerLink]="['/']" >AddCandidate</a></li>
</ul>
<route-outlet></router-outlet>
6
Levi Fuller 11 Июн 2016 в 17:21

Я использую угловой маршрутизатор ^3.4.7, и у меня все еще есть проблемы с директивой routerLinkActive.

Это не работает, если у вас есть несколько ссылок с одним и тем же URL-адресом, и, кажется, не обновляется все время.

Вдохновленный ответом @tomaszbak, я создал небольшой компонент для выполнения этой работы

0
RPDeshaies 16 Фев 2017 в 20:13

Допустим, вы хотите добавить CSS в мое активное состояние / вкладку. Используйте routerLinkActive , чтобы активировать ссылку маршрутизации.

примечание: 'active' - это мое имя класса здесь

<style>
   .active{
       color:blue;
     }
</style>

  <a routerLink="/home" [routerLinkActive]="['active']">Home</a>
  <a routerLink="/about" [routerLinkActive]="['active']">About</a>
  <a routerLink="/contact" [routerLinkActive]="['active']">Contact</a>
1
UniCoder 12 Июн 2017 в 13:52

Простое решение для пользователей angular 5 - просто добавьте routerLinkActive к элементу списка.

Директива routerLinkActive связана с маршрутом через директиву routerLink.

Он принимает в качестве входных данных массив классов, которые он добавит к элементу, к которому он присоединен, если его маршрут в данный момент активен, например, так:

<li class="nav-item"
    [routerLinkActive]="['active']">
  <a class="nav-link"
     [routerLink]="['home']">Home
  </a>
</li>

Приведенное выше добавит класс active к тегу привязки, если мы в данный момент просматриваем домашний маршрут.

Demo

2
Prasanth Jaya 17 Апр 2018 в 10:19

Для маркировки активных маршрутов можно использовать routerLinkActive

<a [routerLink]="/user" routerLinkActive="some class list">User</a>

Это также работает на других элементах, таких как

<div routerLinkActive="some class list">
  <a [routerLink]="/user">User</a>
</div>

Если частичное совпадение также следует пометить, используйте

routerLinkActive="some class list" [routerLinkActiveOptions]="{ exact: false }"

Насколько я знаю exact: false будет по умолчанию в RC.4

14
Community 23 Май 2017 в 11:55

Чистый HTML шаблон будет похож

 <a [routerLink]="['/home']" routerLinkActive="active">Home</a>
 <a [routerLink]="['/about']" routerLinkActive="active">About us</a>
 <a [routerLink]="['/contact']" routerLinkActive="active">Contacts</a>
0
Bellash 22 Июн 2018 в 13:05

Начиная с Angular 8, это работает:

<li routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
    <a [routerLink]="['/']">Home</a>
</li>

{ exact: true } гарантирует, что он соответствует URL.

2
John Kennedy 30 Июн 2019 в 05:07

Решение для Angular2 RC 4:

import {containsTree} from '@angular/router/src/url_tree';
import {Router} from '@angular/router';

export function isRouteActive(router: Router, route: string) {
   const currentUrlTree = router.parseUrl(router.url);
   const routeUrlTree = router.createUrlTree([route]);
   return containsTree(currentUrlTree, routeUrlTree, true);
}
6
lukaville 12 Июл 2016 в 12:09