JavaRush /Курсы /Модуль 4: Node.js, Next.js и Angular /Декларативная навигация: r...

Декларативная навигация: routerLink, routerLinkActive

Модуль 4: Node.js, Next.js и Angular
18 уровень , 3 лекция
Открыта

1. Директива routerLink: Angular-замена href

Вспомните, как мы делали переходы между страницами в старых добрых HTML-сайтах: просто писали <a href="/about.html">О нас</a>. Клик — и браузер грузит новую страницу, моргает, пропадает всё состояние, и жизнь начинается с чистого листа.

В SPA (Single Page Application) на Angular мы хотим, чтобы переход между страницами был быстрым, без перезагрузки, с сохранением состояния приложения. Для этого Angular использует свою систему маршрутизации, а переходы между "страницами" (на самом деле — компонентами) происходят внутри приложения, без полной перезагрузки.

Вместо обычного <a href="..."> мы используем специальные директивы Angular — это и есть декларативная навигация: вы объявляете в шаблоне, куда должен вести переход, а Angular делает всю магию за вас.

Основная идея

routerLink — это директива, которая указывается на тегах (обычно <a>, но можно и на <button>, <li>, <div> — на чём душе угодно), чтобы при клике Angular сам обработал переход по маршруту внутри приложения.

Пример:

<a routerLink="/about">О нас</a>
<a routerLink="/users">Пользователи</a>

При клике на такую ссылку Angular не перезагрузит страницу, а просто подменит компонент в <router-outlet> и обновит URL.

Синтаксис

Строка:

<a routerLink="/contacts">Контакты</a>

Массив:

<a [routerLink]="['/user', userId]">Профиль</a>

Это эквивалентно переходу на /user/42, если userId = 42.

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

<a [routerLink]="['/products', product.id]">{{ product.name }}</a>

Почему массив? Потому что так проще подставлять переменные и формировать сложные маршруты. Это как собирать адрес из кусочков.

2. Примеры использования routerLink в шаблоне

Пример 1: Простое меню

<nav>
  <a routerLink="/">Главная</a>
  <a routerLink="/about">О нас</a>
  <a routerLink="/contacts">Контакты</a>
</nav>

Пример 2: Список пользователей с переходом по id

<ul>
  <li *ngFor="let user of users">
    <a [routerLink]="['/users', user.id]">{{ user.name }}</a>
  </li>
</ul>

Пример 3: Кнопка для перехода

<button [routerLink]="['/create']">Создать</button>

Да, можно использовать routerLink не только на <a>, но и на других тегах.

routerLink vs href: в чём разница?

  • href — это переход "по-настоящему", браузер загружает новую страницу.
  • routerLink — это "виртуальный" переход внутри Angular-приложения: компонент меняется, страница не перезагружается, состояние приложения сохраняется.

Важный нюанс:
Если вы используете обычный <a href="..."> в Angular-приложении, то браузер уйдёт с вашего SPA, и все данные приложения потеряются. Поэтому для внутренних переходов всегда используйте routerLink.

3. routerLinkActive: активная ссылка и подсветка текущего маршрута

Навигация — это не только переходы, но и подсветка того пункта меню, который сейчас активен. Пользователь должен понимать, где он находится. В Angular для этого есть директива routerLinkActive.

Как работает?

routerLinkActive добавляет CSS-класс к элементу, если маршрут, на который ссылается этот элемент, совпадает с текущим URL.

Пример:

<nav>
  <a routerLink="/" routerLinkActive="active-link" [routerLinkActiveOptions]="{ exact: true }">Главная</a>
  <a routerLink="/about" routerLinkActive="active-link">О нас</a>
  <a routerLink="/contacts" routerLinkActive="active-link">Контакты</a>
</nav>

Теперь, когда вы находитесь на /about, ссылка "О нас" будет иметь класс active-link. Можно стилизовать этот класс в CSS:

.active-link {
  font-weight: bold;
  color: #1976d2;
  border-bottom: 2px solid #1976d2;
}

Важный момент: [routerLinkActiveOptions]
По умолчанию routerLinkActive срабатывает, если URL начинается с указанного маршрута. То есть, если вы находитесь на /about/team, то ссылка с routerLink="/about" тоже будет активной.

Чтобы этого избежать и подсвечивать только при полном совпадении, используйте:

<a routerLink="/about" routerLinkActive="active-link" [routerLinkActiveOptions]="{ exact: true }">О нас</a>

4. Полезные нюансы

routerLinkActive с вложенными меню и несколькими маршрутами

routerLinkActive можно указать сразу на родительском элементе, чтобы подсвечивать, например, пункт списка <li>, а не только саму ссылку.

Пример:

<ul>
  <li routerLinkActive="active-item">
    <a routerLink="/dashboard">Панель</a>
  </li>
  <li routerLinkActive="active-item">
    <a routerLink="/settings">Настройки</a>
  </li>
</ul>

Теперь класс active-item будет назначаться на <li>, и вы сможете делать, например, красивую подсветку фона всей строки.

Динамические ссылки и параметры

Часто приходится формировать маршруты с параметрами — например, переходить на страницу пользователя по его id.

<a [routerLink]="['/users', user.id]">{{ user.name }}</a>

Если у вас есть дополнительные query параметры, их можно добавить так:

<a [routerLink]="['/products']" [queryParams]="{ category: 'books', sort: 'price' }">
  Книги по цене
</a>

В результате получится адрес /products?category=books&sort=price.

routerLink с фрагментами (anchor)

Можно добавить якорь (фрагмент, то, что после #) к ссылке:

<a [routerLink]="['/about']" fragment="team">О нашей команде</a>

Это приведёт к URL /about#team.

routerLink и относительная навигация

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

Пример (продвинутый):

<!-- Переход на подмаршрут относительно текущего -->
<a [routerLink]="['details']" [relativeTo]="route">Подробнее</a>

В коде компонента:

constructor(public route: ActivatedRoute) {}

Для большинства задач достаточно абсолютных маршрутов.

5. Практика: создаём меню для учебного приложения

Предположим, у нас есть простое приложение с такими маршрутами:

  • / — Главная
  • /users — Список пользователей
  • /users/:id — Страница пользователя
  • /about — О нас

Создадим компонент меню:

<nav>
  <a routerLink="/" routerLinkActive="active-link" [routerLinkActiveOptions]="{ exact: true }">Главная</a>
  <a routerLink="/users" routerLinkActive="active-link">Пользователи</a>
  <a routerLink="/about" routerLinkActive="active-link">О нас</a>
</nav>

В компоненте пользователей:

<ul>
  <li *ngFor="let user of users">
    <a [routerLink]="['/users', user.id]" routerLinkActive="active-link">{{ user.name }}</a>
  </li>
</ul>

В CSS:

.active-link {
  color: #1976d2;
  font-weight: bold;
  text-decoration: underline;
}

6. Типичные ошибки при работе с routerLink и routerLinkActive

Ошибка №1: Использование href вместо routerLink для внутренних переходов.
Это приводит к полной перезагрузке страницы и потере состояния приложения. Если вы видите, что при переходе моргает страница — проверьте, не забыли ли вы заменить href на routerLink.

Ошибка №2: routerLink без слэша в начале.
Если написать routerLink="about", Angular воспримет это как относительный путь. Обычно для перехода в корень используйте слэш: routerLink="/about".

Ошибка №3: routerLinkActive не подсвечивает ссылку.
Часто связано с тем, что путь не совпадает полностью. Используйте [routerLinkActiveOptions]="{ exact: true }" для точного совпадения.

Ошибка №4: Несовпадение маршрута и ссылки.
Если маршрут определён как /users/:id, а вы пишете просто routerLink="/users", переход произойдёт не на конкретного пользователя, а на список. Для перехода на страницу пользователя используйте массив: [routerLink]="['/users', user.id]".

Ошибка №5: Забыли импортировать RouterModule.
Если директивы не работают и Angular ругается на неизвестные атрибуты — проверьте, что в вашем модуле импортирован RouterModule.

Ошибка №6: routerLink на неинтерактивных элементах без tabindex.
Если вы хотите, чтобы <div routerLink="..."> был доступен для клавиатуры, добавьте tabindex="0" и обработку нажатия клавиш.

Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ