javascript - route - В Angular как вы определяете активный маршрут?




angular routing page title (19)

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

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

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

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

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


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

ОБНОВЛЕНИЕ: обновлено согласно 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
}

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


А в последней версии 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>

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


Вот полный пример добавления активного стиля маршрута в Angular версии 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>

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

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

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

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

import {Location} from "angular2/router";

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


Для маркировки активных маршрутов можно использовать 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


Еще один обходной путь. Гораздо проще в 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>

Как упомянуто в одном из комментариев принятого ответа, директива 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 .


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

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

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


Ниже приведен метод использования 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;
  }
}

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

RC4 и RC3 :

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

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

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

Больше о директиве routerLinkActive по этой angular.io/docs/ts/latest/api/router/index/… .

Для применения класса к любому 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>

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

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

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

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

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


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

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

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


С новым маршрутизатором Angular вы можете добавить [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>

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

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


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

 <a [routerLink]="['/home']" routerLinkActive="active">Home</a>
 <a [routerLink]="['/about']" routerLinkActive="active">About us</a>
 <a [routerLink]="['/contact']" routerLinkActive="active">Contacts</a>

Я искал способ использовать навигацию в стиле 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 ){}
}

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

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

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


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

@Component({
   styles: [`.router-link-active { background-color: red; }`]
})
export class NavComponent {
}

допустим, вы хотите добавить 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>

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 должен быть routeSegment : RouteSegment в конструктор компонента.





angular2-routing