В Angular, как вы определяете активный маршрут?
Примечание:есть много разных ответов здесь, и большинство из них были действительны в то или иное время. Дело в том, что то, что работает, изменилось несколько раз, когда команда Angular изменила свой маршрутизатор. Версия маршрутизатора 3.0, которая в конечном итоге будет the маршрутизатор в угловых перерывах многие из этих решений, но предлагает очень простое решение самостоятельно. По состоянию на RC.3, предпочтительным решением является использование [routerLinkActive] как показано в этот ответ.
в угловом приложении (ток в 2.0.0-бета.Выпуск 0 как я пишу это), как вы определяете, что в настоящее время активный маршрут?
Я работаю над приложением, которое использует Bootstrap 4, и мне нужен способ пометить навигационные ссылки / кнопки как активные, когда их связанный компонент отображается в <router-output> тег.
Я понимаю, что я мог поддерживать состояние себя, когда одна из кнопок нажата, но это не покройте случай наличия нескольких путей в один и тот же маршрут (скажем, главное меню навигации, а также локальное меню в главном компоненте).
любые предложения или ссылки будут оценены. Спасибо.
25 ответов:
новая Угловое маршрутизатор, вы можете добавить
[routerLinkActive]="['your-class-name']"атрибут для всех ваших ссылок:<a [routerLink]="['/home']" [routerLinkActive]="['is-active']">Home</a>или упрощенный формат без массива, если требуется только один класс:
<a [routerLink]="['/home']" [routerLinkActive]="'is-active'">Home</a>посмотреть плохо документированы
routerLinkActiveдиректива для получения дополнительной информации. (Я в основном понял это методом проб и ошибок.)обновление: лучшая документация для
routerLinkActiveдиректива теперь может быть найдена здесь. (Спасибо @Victor Hugo Arango A. в комментариях ниже.)
я ответил на это в другом вопросе, но я считаю, что это может иметь отношение и к этому. Вот ссылка на оригинальный ответ: угловой 2: Как определить активный маршрут с параметрами?
я пытался установить активный класс без необходимости точно знать, что такое текущее местоположение (используя название маршрута). Это лучшее решение, которое я получил до сих пор с помощью функции isRouteActive доступно в
Routerкласса.
router.isRouteActive(instruction): Booleanпринимает один параметр, который является по маршрутуInstructionобъект и возвращаетtrueилиfalseвыполняется ли эта инструкция для текущего маршрута. Вы можете создать маршрутInstructionС помощьюRouter' s generate (linkParams: Array). LinkParams следует точно такому же формату, как и значение, переданное в routerLink
Я решил проблему, с которой столкнулся в этом ссылке и я узнаю, что есть простое решение для вашего вопроса. Вы могли бы использовать
router-link-activeа в ваших стилях.@Component({ styles: [`.router-link-active { background-color: red; }`] }) export class NavComponent { }
небольшое улучшение @alex-correia-santos ответ на основе https://github.com/angular/angular/pull/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>
вы можете проверить текущий маршрут, введя
Locationобъект в контроллер и проверкаpath(), например:class MyController { constructor(private location:Location) {} ... location.path(); ... }вам нужно будет сначала импортировать его:
import {Location} from "angular2/router";затем вы можете использовать регулярное выражение для сопоставления с возвращенным путем, чтобы увидеть, какой маршрут активен. Обратите внимание, что
Locationкласс возвращает нормализованный путь независимо от того, какойLocationStrategyвы используете. Так что даже если вы используетеHashLocationStragegyпути вернулся все равно будет иметь вид/foo/barне#/foo/bar
Как вы определяете, что в настоящее время активный маршрут?
обновление: Обновлено в соответствии с 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 }
Ниже приведен метод, использующий RouteData для стилизации элементов меню в зависимости от текущего маршрута:
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; } }
вот полный пример для добавления активного стиля маршрута в угловой версии
2.0.0-rc.1который учитывает нулевые корневые пути (например,path: '/')приложение.деталь.ТС -> маршруты
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; } }приложение.деталь.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>
решение для 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); }
сейчас я использую rc.4 с bootstrap 4 и этот работает идеально подходит для меня:
<li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}"> <a class="nav-link" [routerLink]="['']">Home</a> </li>Это будет работать для url: / home
чтобы отметить активные маршруты
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
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должен быть введен в конструкторе компонента.
экземпляр класса маршрутизатора на самом деле является наблюдаемым, и он возвращает текущий путь каждый раз, когда он изменяется. Вот как я это делаю:
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>
Еще Один Обходной Путь. Гораздо проще в 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>
в Angular2 RC2 вы можете использовать эту простую реализацию
<a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>это добавит класс
activeк элементу с соответствующим url, подробнее об этом здесь
Ниже приведены ответы на этот вопрос для всех версий Angular 2 RC версий, выпущенных до настоящего времени:
RC4 и RC3:
для применения класса к ссылке или предку ссылки:
<li routerLinkActive="active"><a [routerLink]="['/home']">Home</a></li>/ home должен быть URL, а не имя маршрута, так как свойство name больше не существует на объекте маршрута с маршрутизатора v3.
подробнее о директиве routerLinkActive на этом ссылке.
для применения класса к любому div на основе текущего маршрута:
- внедрить маршрутизатор в конструктор компонента.
- маршрутизатор.URL для сравнения.
Эл.г
<nav [class.transparent]="router.url==('/home')"> </nav>RC2 и RC1:
используйте комбинацию маршрутизатора.isRouteActive и класс.*. например, чтобы применить активный класс на основе домашнего маршрута.
имя и url могут быть переданы в обращать в бегство.генерировать.
<li [class.active]="router.isRouteActive(router.generate(['Home']))"> <a [routerLink]="['Home']" >Home</a> </li>
используя
routerLinkActiveхорош в простых случаях, когда есть ссылка и вы хотите применить некоторые классы. Но в более сложных случаях, когда у вас может не быть routerLink или вам нужно что-то еще, вы можете создать и использовать труба:@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>и не забудьте включить трубы в зависимости труб;)
как уже упоминалось в одном из комментариев принятого ответа,
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>тега
для угловой версии 4+ Вам не нужно использовать какое-либо сложное решение. Вы можете просто использовать
[routerLinkActive]="'is-active'".для примера с bootstrap 4 nav link:
<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>
просто подумал, что я хотел бы добавить в пример, который не использует никакого машинописного текста:
<input type="hidden" [routerLink]="'home'" routerLinkActive #home="routerLinkActive" /> <section *ngIf="home.isActive"></section>The
routerLinkActiveпеременная привязывается к переменной шаблона, а затем повторно используется по мере необходимости. К сожалению, единственный нюанс заключается в том, что вы не можете иметь все это на<section>элемент#homeдолжен быть решен до чтобы парсер ударил<section>.
Я искал способ использовать Twitter Bootstrap style nav с 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 ){} }
допустим, вы хотите добавить CSS в мое активное состояние/вкладку. Используйте routerLinkActive активировать ссылку маршрут.
Примечание: "активный" - это мое имя класса здесь
<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>
простое решение для угловых пользователей 5, просто добавьте
routerLinkActiveк элементу списка.A
routerLinkActiveдиректива связана с маршрутом через a
чистый html шаблон быть как
<a [routerLink]="['/home']" routerLinkActive="active">Home</a> <a [routerLink]="['/about']" routerLinkActive="active">About us</a> <a [routerLink]="['/contact']" routerLinkActive="active">Contacts</a>
Comments