Маршрутизация

Определение маршрутов

Последнее обновление: 16.11.2023

Маршрутизация позволяет сопоставлять запросы к приложению с определенными ресурсами внутри приложения.

Ключевым для работы маршрутизации является модуль RouterModule, который располагается в пакете @angular/router. Поэтому при работе с маршрутизацией этот пакет должен быть указан в списке зависимостей в файле package.json:

{
    "name": "helloapp",
    "version": "1.0.0",
    "description": "First Angular 17 Project",
    "author": "Eugene Popov <metanit.com>",
    "scripts": {
        "ng": "ng",
		"start": "ng serve",
		"build": "ng build"
    },
    "dependencies": {
        "@angular/router": "~17.0.0",
        // остальные пакеты
    },
    "devDependencies": {
         
        // остальные пакеты
    }
}

Для определения маршрутов возьмем базовую структуру приложения:

RouterModule в Angular

Для работы с маршрутизацией в первую очередь стоит определить базовый адрес приложения. Для этого возьмем веб-страницу index.html и добавим в секцию <head> элемент <base>:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <base href="/" />
    <title>Hello Angular 17</title>
</head>
<body>
    <my-app>Загрузка...</my-app>
</body>
</html>

В качестве базового адреса будет рассматриваться корень приложения.

Каждый маршрут сопоставляется с определенным компонентом. Поэтому добавим в проект ряд компонентов. Так, добавим в папку src/app новый файл home.component.ts:

import { Component} from "@angular/core";
 
@Component({
    selector: "home-app",
    template: "<h2>Главная</h2>"
})
export class HomeComponent { }

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

Далее добавим в папку src/app новый файл about.component.ts:

import { Component} from "@angular/core";
 
@Component({
    selector: "about-app",
    template: "<h2>О сайте</h2>"
})
export class AboutComponent { }

И также добавим еще один файл not-found.component.ts:

import { Component} from "@angular/core";
 
@Component({
    selector: "not-found-app",
    template: "<h2>Страница не найдена</h2>"
})
export class NotFoundComponent { }

Добавление и установка маршрутов

Итак, кроме главного компонента AppComponent в проекте определено еще три компонента, каждый из которых просто выводит некоторый заголовок. Для каждого из этих компонентов мы можем определить свой маршрут. Для этого добавим в папке src/app новый файл app.config.ts со следующим содержимым:

import { provideRouter, Routes } from "@angular/router";
import { ApplicationConfig } from "@angular/core";

// компоненты, которые сопоставляются с маршрутами
import {HomeComponent} from "./home.component";
import {AboutComponent} from "./about.component";
import {NotFoundComponent} from "./not-found.component";

// определение маршрутов
const appRoutes: Routes =[
    { path: "", component: HomeComponent},
    { path: "about", component: AboutComponent},
    { path: "**", component: NotFoundComponent }
];

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(appRoutes)]
};

Во-первых, здесь импортируются функция providerRouter (для установки маршрутов) и класс Routes, который представляет коллекцию маршрутов:

import { provideRouter, Routes } from "@angular/router";

Для приложения маршруты устанавливаются как часть конфигурации приложения, которая представляет класс ApplicationConfig. Соответственно также импортируем данный класс:

import { ApplicationConfig } from "@angular/core";

Далее определяется сам набор маршрутов:

import {HomeComponent} from "./home.component";
import {AboutComponent} from "./about.component";
import {NotFoundComponent} from "./not-found.component";

// определение маршрутов
const appRoutes: Routes =[
    { path: "", component: HomeComponent},
    { path: "about", component: AboutComponent},
    { path: "**", component: NotFoundComponent }
];

Здесь определено три маршрута, каждый из которых будет обрабатываться отдельным компонентом. Для указания маршрута применяется параметр path. Например, путь "about" будет представлять запрос типа "http://localhost:3000/about" и будет обрабатываться классом AboutComponent.

Если запрос не содержит никаких сегментов, например, просто имя домена "http://localhost:3000/", то такой запрос будет сопоставляться с путем "" (пустая строка) и будет обрабатываться компонентом HomeComponent.

Если приложение получит запрос, который не подходит ни под один из выше определенных маршрутов, то он будет сопоставляться с шаблоном "**", где две звездочки представляют любой путь.

Чтобы применить маршруты, создаем объект ApplicationConfig и устанавливаем его свойство providers:

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(appRoutes)]
};

Здесь в коллекцию providers передается результат функции provideRouter(). Эта функция принимает коллекцию маршрутов Routes и использует их для настройки сервиса Router. Когда приложение загружается, Router выполняет начальную навигацию по текущему URL, который стоит в адресной строке браузера.

Однако мы только определили конфигурацию приложения в виде объекта appConfig. Теперь его надо применить к приложению. Для этого перейдем к файлу main.ts и изменим его следующим образом:

import { bootstrapApplication } from "@angular/platform-browser";
import { AppComponent } from "./app/app.component";
import {appConfig} from "./app/app.config";
bootstrapApplication(AppComponent, appConfig);

Вторым, необязательным параметров функции bootstrapApplication() передается конфигурация приложения ApplicationConfig. И в данном случае передаем наш объект appConfig, который будет настраивать систему маршрутизации.

RouterOutlet

Мы определили три разных компонента для разных маршрутов, однако в качестве главного компонента выступает AppComponent. Этот компонент выступает в качестве контейнера для остальных компонентов, которые будут обслуживать запросы к приложению.

Но чтобы можно было внедрить в AppComponent тот компонент, который обрабатывает запрос, необходимо использовать элемент RouterOutlet. Для этого изменим код AppComponent:

import { Component} from "@angular/core";
import { RouterOutlet} from "@angular/router";

@Component({
    selector: "my-app",
    standalone: true,
    imports: [RouterOutlet],
    template: `<div>
                    <h1>Приложение Angular</h1>
                    <router-outlet></router-outlet>
               </div>`,
})
export class AppComponent {}

На место элемента <router-outlet> будет рендериться компонент, выбранный для обработки запроса.

В итоге проект будет выглядеть следующим образом:

Установка маршрутов в Angular

Запустим приложение. По умолчанию приложение запускается без сегментов, поэтому запрос обрабатывает HomeComponent:

Маршруты в Angular

Перейдем по пути "localhost:xxxx/about":

Routes в Angular

При переходе к любому другому адресу сработает компонент NotFoundComponent:

Маршрутизация в Angular

URL Matching и порядок маршрутов

Когда будет выполняться переход по определенному пути, например, "/about", система маршрутизации сопоставляет последовательно URL запроса с параметрами path у каждого маршрута. Данный процесс называется url matching. В частности, система маршрутизации сопоставит url "/about" с маршрутом { path: "about", component: AboutComponent}. И компонент AboutComponent будет выбран для обработки запроса по пути /about.

Но при определении маршрутов следует учитывать их порядок. Вполне возможно, что под определенный запрос будет соответствовать сразу несколько маршрутов. В этом случае запрос будет обрабатываться первым из них. Другие же маршруты не будут учитываться. Например, если мы изменим порядок маршрутов:

const appRoutes: Routes =[
	{ path: "**", component: NotFoundComponent },
	{ path: "", component: HomeComponent},
	{ path: "about", component: AboutComponent}
];

То в этом случае запрос /about будет обрабатываться первым маршрутом, поскольку он соответствует запросу /about (путь "**" соответствует любому набору символов). Поэтому маршрут

{ path: "**", component: NotFoundComponent }

лучше определить последним - для всех тех запросов, которые не будут соответствовать ни одному из выше определенных маршрутов.

Переадресация

Вполне возможно, что по какому-то маршруту мы захотим сделать переадресацию по другому пути. Например, в случае, если нужного маршрута для запроса не найдено, мы можем переадресовать на главную страницу:

const appRoutes: Routes =[
	{ path: "", component: HomeComponent},
	{ path: "about", component: AboutComponent},
	{ path: "**", redirectTo: "/"}
];

Для переадресации указываем параметр redirectTo. Его значение представляет путь переадресации. В данном случае слеш указывает на первый маршрут или на главную страницу.

Также мы можем задать критерий соответствия строки запроса маршруту с помощью параметра pathMatch:

const appRoutes: Routes =[
	{ path: "", component: HomeComponent},
	{ path: "about", component: AboutComponent},
	{ path: "contact", redirectTo: "/about", pathMatch:"full"},
	{ path: "**", redirectTo: "/"}
];

Значение pathMatch:"full" указывает, что запрошенный адрес должен полностью соответствовать маршруту, то есть должно быть полное соответствие. Например, запрос /contact полностью соотвествует маршруту { path: "contact", redirectTo: "/about", pathMatch:"full"}, поэтому будет выполняться переадресация на адрес /about.

А запрос /contact/5 не будет соответствовать этому маршруту, так как после "contact" идут другие сегменты.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850