Как определить активный маршрут (route) в Angular? Определение активного URL и подсветка ссылок
Решение с помощью routerLinkActive (для шаблона)
Angular предоставляет встроенную директиву routerLinkActive для подсветки активных ссылок. Она автоматически добавляет CSS-класс к элементу, когда связанный с ним маршрут активен. Вот как правильно её использовать:
// navigation.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-navigation',
template: `
<nav>
<a routerLink="/dashboard"
routerLinkActive="active"
[routerLinkActiveOptions]="{ exact: true }">
Дашборд
</a>
<a routerLink="/users"
routerLinkActive="active"
[routerLinkActiveOptions]="{ exact: false }">
Пользователи
</a>
<a routerLink="/settings"
routerLinkActive="active"
[routerLinkActiveOptions]="{ exact: true }">
Настройки
</a>
</nav>
`,
styles: [`
.active {
font-weight: bold;
color: #007bff;
border-bottom: 2px solid #007bff;
}
`]
})
export class NavigationComponent {}
Ключевой момент — опция exact в routerLinkActiveOptions:
{ exact: true }— класс добавляется только если URL полностью совпадает сrouterLink. Идеально для корневых маршрутов (например,/dashboard).{ exact: false }(значение по умолчанию) — класс добавляется если URL начинается с указанного пути. Подходит для родительских маршрутов, когда нужно подсвечивать раздел при переходе на дочерние страницы (например,/usersпри/users/123).
Если у вас есть пустой путь (''), он будет совпадать с любым URL. Чтобы избежать этого, всегда используйте exact: true для корневого маршрута или задайте явный путь, например /home.
Программное определение активного маршрута в компоненте
Для получения текущего маршрута в TypeScript используйте сервис Router и объект ActivatedRoute. Вот полный пример:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
import { filter, Subscription } from 'rxjs';
@Component({
selector: 'app-navigation',
template: `
<nav>
<a routerLink="/dashboard">Дашборд</a>
<a routerLink="/users">Пользователи</a>
<a routerLink="/settings">Настройки</a>
</nav>
<p *ngIf="isUsersSection">Вы в разделе пользователей</p>
`
})
export class NavigationComponent implements OnInit, OnDestroy {
currentUrl: string = '';
isUsersSection: boolean = false;
private subscription: Subscription = new Subscription();
constructor(private router: Router, private route: ActivatedRoute) {}
ngOnInit() {
// Подписываемся на события навигации
this.subscription.add(
this.router.events.pipe(
filter(event => event instanceof NavigationEnd)
).subscribe((event: NavigationEnd) => {
this.currentUrl = event.urlAfterRedirects;
this.isUsersSection = this.currentUrl.startsWith('/users');
console.log('Текущий URL:', this.currentUrl);
})
);
// Получаем текущий маршрут при инициализации
this.currentUrl = this.router.url;
this.isUsersSection = this.currentUrl.startsWith('/users');
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
// Альтернативный способ через ActivatedRoute
getCurrentRoutePath(): string {
let route = this.route.root;
let path = '';
while (route.firstChild) {
route = route.firstChild;
if (route.snapshot.url.length > 0) {
path += '/' + route.snapshot.url.join('/');
}
}
return path || '/';
}
}
Разбор кода:
router.events— Observable, который испускает все события роутера. Фильтруем толькоNavigationEnd, чтобы получить момент завершения навигации.event.urlAfterRedirects— конечный URL после всех редиректов (если они есть).router.url— текущий URL на момент вызова (можно использовать в ngOnInit для начального значения).ActivatedRoute— позволяет пройти по дереву маршрутов и собрать путь из сегментов. Полезно для получения параметров маршрута.
Важно: не забывайте отписываться от подписок в ngOnDestroy, чтобы избежать утечек памяти. Альтернативно можно использовать takeUntil из RxJS.
Использование сервиса Location и Router.isActive
Если вам нужно только проверить, активен ли конкретный маршрут в коде компонента (без подписки на все события), можно использовать метод Router.isActive(). Это проще и не требует управления подписками:
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-navigation',
template: `
<button (click)="checkRoute()">Проверить маршрут</button>
<p *ngIf="isDashboardActive">Дашборд активен</p>
`
})
export class NavigationComponent {
isDashboardActive: boolean = false;
constructor(private router: Router) {
// Проверяем при инициализации
this.isDashboardActive = this.router.isActive('/dashboard', true);
}
checkRoute() {
// Проверка с точным совпадением (exact: true)
this.isDashboardActive = this.router.isActive('/dashboard', true);
// Проверка с частичным совпадением (exact: false)
const isUsersSection = this.router.isActive('/users', false);
console.log('В разделе пользователей?', isUsersSection);
}
}
Преимущества:
- Нет необходимости подписываться на события — метод возвращает булево значение синхронно.
- Второй параметр
exactработает аналогичноrouterLinkActiveOptions. - Можно использовать в шаблоне через метод, но будьте осторожны — вызов метода в шаблоне может привести к частым перерисовкам. Лучше сохранять результат в свойство.
Недостаток: метод не обновляется автоматически при смене маршрута. Вам нужно вызывать его вручную (например, в обработчике клика или через подписку на NavigationEnd, если требуется реактивность).
Для простых случаев, когда нужно проверить маршрут по событию (например, при клике на кнопку), Router.isActive() — самое лаконичное решение.
Ответов пока нет.
Войдите чтобы оставить ответ