AI Angular Router для начинающих: понятный гайд с примерами

AI

Редактор
Регистрация
23 Август 2023
Сообщения
2 819
Лучшие ответы
0
Реакции
0
Баллы
51
Offline
#1

Введение


Представьте, что вы делаете сайт-визитку или интернет-магазин на Angular. У вас есть главная страница, страница «О нас» и страница с товарами. Логично, что при клике на ссылки пользователь должен переходить между этими страницами

В классических сайтах это решается просто: при каждом клике браузер запрашивает у сервера новую HTML-страницу. Но в современных SPA (Single Page Applications) всё работает иначе — приложение загружается один раз, а дальше мы просто подменяем содержимое внутри него

Именно за это отвечает Angular Router. Он позволяет:


  • описывать маршруты (какой URL → какой компонент);


  • переключаться между страницами без перезагрузки;


  • передавать параметры и query-параметры в адресной строке;


  • защищать маршруты с помощью Guard’ов;


  • подгружать части приложения по требованию (lazy loading).

Можно сказать, что Router — это сердце навигации в Angular-приложениях. Если вы его поймёте, то сможете строить полноценные многостраничные приложения, а не просто «выводить компонент на экран»

В этой статье мы разберём Angular Router пошагово: от простейшего примера с тремя страницами до более продвинутых вещей вроде Guard’ов и ленивой загрузки. Всё будет на живых примерах и максимально простым языком, чтобы вы смогли уверенно применить это в реальном проекте

Мини-проект: Pizza Router App 🍕


Чтобы разобраться с Angular Router, мы будем делать маленький сайт пиццерии. У него будут такие страницы:


  • / — Главная (приветственный экран + популярные пиццы),


  • /menu — Меню (список всех пицц),


  • /pizza/:id — Детальная страница пиццы (динамический роут),


  • /contacts — Контакты.

По ходу статьи мы добавим:


  • queryParams (например, сортировка пицц по цене),


  • Guard (например, «только авторизованный пользователь может сделать заказ»),


  • Lazy loading (например, админка для добавления новых пицц).
1. Создаём страницы для пиццерии 🍕


Сначала сгенерируем компоненты:

ng g c components/home
ng g c components/menu
ng g c components/pizza
ng g c components/contacts

Теперь у нас есть 4 компонента. Заполним их простым содержимым.

home.html

<h1>🍕 Добро пожаловать в Pizza Router App!</h1>
<p>Здесь вы можете выбрать вкусную пиццу и заказать её онлайн</p>
<a routerLink="/menu">Перейти в меню</a>

menu.ts

import { Component } from '@angular/core';

@Component({
selector: 'app-menu',
imports: [],
templateUrl: './menu.html',
styleUrl: './menu.scss'
})
export class Menu {
pizzas = [
{ id: 1, name: 'Маргарита', price: 450 },
{ id: 2, name: 'Пепперони', price: 550 },
{ id: 3, name: 'Четыре сыра', price: 600 },
];
}

menu.html

<h2>Меню пицц</h2>
<ul>
@for (pizza of pizzas; track pizza.id) {
<li>
<a [routerLink]="['/pizza', pizza.id]">
{{ pizza.name }} — {{ pizza.price }} ₽
</a>
</li>
}
</ul>

pizza.ts

Здесь используем динамический параметр id

import {Component, inject, OnInit} from '@angular/core';
import {ActivatedRoute, RouterLink} from '@angular/router';

@Component({
selector: 'app-pizza',
imports: [
RouterLink
],
templateUrl: './pizza.html',
styleUrl: './pizza.scss'
})
export class Pizza implements OnInit {
private readonly route = inject(ActivatedRoute);
pizzaId: string | null = null;

ngOnInit() {
this.pizzaId = this.route.snapshot.paramMap.get('id');
}
}


pizza.html

<h2>Вы выбрали пиццу №{{ pizzaId }}</h2>
<p>Здесь могла бы быть подробная информация о пицце (ингредиенты, фото, отзывы)</p>
<a routerLink="/menu">⬅ Назад в меню</a>


contacts.html

<h2>Контакты</h2>
<p>📍 Адрес: ул. Angular, 42</p>
<p>📞 Телефон: +7 (999) 123-45-67</p>
2. Настраиваем роутинг


Angular Router уже встроен, нужно лишь добавить наши роуты

// app.routes.ts

import {Routes} from '@angular/router';
import {Home} from './components/home/home';
import {Menu} from './components/menu/menu';
import {Pizza} from './components/pizza/pizza';
import {Contacts} from './components/contacts/contacts';

export const routes: Routes = [
{path: '', component: Home},
{path: 'menu', component: Menu},
{path: 'pizza/:id', component: Pizza},
{path: 'contacts', component: Contacts},
];


Теперь в app.html добавим навигацию и место, где будут подставляться страницы:

<nav>
<a routerLink="/">Главная</a> |
<a routerLink="/menu">Меню</a> |
<a routerLink="/contacts">Контакты</a>
</nav>

<!-- Сюда Angular будет рендерить выбранный компонент -->
<router-outlet></router-outlet>


Если сейчас запустить проект (ng serve), то можно уже кликать по ссылкам и переходить между компонентами 🎉

3. Дополнительные параметры маршрутов


У объекта маршрута можно указывать не только path и component. Вот самые важные:

redirectTo


Позволяет перенаправить пользователя на другой маршрут

{ path: '', redirectTo: 'menu', pathMatch: 'full' }

Теперь при заходе на / сразу откроется страница меню

pathMatch


Указывает, как сравнивать путь.


  • full — путь должен совпадать полностью


  • prefix — совпадение по началу

{ path: '', redirectTo: 'menu', pathMatch: 'full' }

Если бы мы поставили prefix, редирект срабатывал бы слишком часто (например, даже при /pizza/1)

title


Начиная с Angular 14, можно указывать заголовок страницы прямо в маршруте

{ path: 'menu', component: Menu, title: 'Меню пицц' }

Теперь при переходе на /menu в браузере будет Pizza Router App - Меню пицц

children


Для вложенных маршрутов. Например, сделаем «Личный кабинет»:

{
path: 'profile',
component: ProfileLayout,
children: [
{ path: 'orders', component: Orders },
{ path: 'settings', component: Settings },
]
}
canActivate


Для защиты маршрута. Например, доступ к профилю только авторизованным:

{ path: 'profile', component: ProfileLayout, canActivate: [AuthGuard] }

Ленивая загрузка (Lazy Loading) в Angular Router


По умолчанию Angular загружает весь код приложения при старте. Если проект маленький — это нормально. Но когда страниц становится десятки и сотни (например, интернет-магазин с личным кабинетом, админкой, корзиной, заказами) → bundle разрастается и первая загрузка приложения становится медленной

Как решает проблему Lazy Loading?

Мы можем «разбить» приложение на модули, и загружать их только тогда, когда пользователь реально заходит на этот раздел

Например, в нашем приложении «Пиццерия»:


  • обычным клиентам нужны только Главная, Меню, Контакты;


  • а вот админку (/admin) им загружать нет смысла
Базовый пример


Допустим, у нас есть такой роутинг

import {Routes} from '@angular/router';
import {Home} from './components/home/home';
import {Menu} from './components/menu/menu';
import {Pizza} from './components/pizza/pizza';
import {Contacts} from './components/contacts/contacts';

export const routes: Routes = [
{path: 'menu', component: Menu},
{path: 'pizza/:id', component: Pizza},
{path: 'contacts', component: Contacts},
{ path: '', redirectTo: 'menu', pathMatch: 'full' }
];


Теперь добавим ленивый роут для админки:

export const routes: Routes = [
{ path: 'menu', component: Menu },
{ path: 'pizza/:id', component: Pizza },
{ path: 'contacts', component: Contacts },
{ path: '', redirectTo: 'menu', pathMatch: 'full' },

// 👇 ленивый роут со standalone компонентом
{
path: 'admin',
loadComponent: () =>
import('./pages/admin/admin').then(m => m.Admin),
},
];
Поддержка вложенных маршрутов


Если админка сложнее и у неё есть вложенные страницы (/admin/orders, /admin/settings), то лучше вынести их в отдельный routes

export const routes: Routes = [
{ path: 'menu', component: Menu },
{ path: 'pizza/:id', component: Pizza },
{ path: 'contacts', component: Contacts },
{ path: '', redirectTo: 'menu', pathMatch: 'full' },

{
path: 'admin',
loadChildren: () =>
import('./pages/admin/admin.routes').then(m => m.adminRoutes),
},
];

А внутри admin.routes.ts:

import { Routes } from '@angular/router';
import { AdminDashboard } from './dashboard/dashboard';
import { AdminOrders } from './orders/orders';

export const adminRoutes: Routes = [
{ path: '', component: AdminDashboard },
{ path: 'orders', component: AdminOrders },
];

Когда использовать loadComponent, а когда loadChildren?


  • loadComponent — когда у тебя одна страница, типа /admin.


  • loadChildren — когда у тебя несколько маршрутов внутри раздела, например /admin/orders, /admin/settings
🎯 Заключение


Мы прошли большой путь:


  • разобрали базовые маршруты (path, component),


  • научились работать с параметрами :)id, queryParams),


  • посмотрели на дополнительные настройки (redirectTo, pathMatch, title),


  • сделали ленивая загрузку и вложенные роуты

Теперь вы знаете, как устроен Angular Router и можете уверенно использовать его в своих проектах

Хотите маленький сайт-визитку, интернет-магазин или целую админку — всё это реально построить на тех знаниях, что мы разобрали
 

Похожие темы

Сверху Снизу