Полное руководство по маршрутизации в Angular
Опубликовано: 2022-03-10Если вы еще не совсем знакомы с Angular 7, я хотел бы познакомить вас со всем, что может предложить этот впечатляющий интерфейсный фреймворк. Я познакомлю вас с демонстрационным приложением Angular, в котором показаны различные концепции, связанные с маршрутизатором, такие как:
- Розетка роутера,
- Маршруты и пути,
- Навигация.
Я также покажу вам, как использовать Angular CLI v7 для создания демонстрационного проекта, в котором мы будем использовать маршрутизатор Angular для реализации маршрутизации и навигации. Но сначала позвольте мне представить вам Angular и рассказать о некоторых важных новых функциях в его последней версии.
Представляем Angular 7
Angular — один из самых популярных интерфейсных фреймворков для создания клиентских веб-приложений для мобильных и десктопных веб-приложений. Он следует архитектуре, основанной на компонентах, где каждый компонент представляет собой изолированный и повторно используемый фрагмент кода, который управляет частью пользовательского интерфейса приложения.
Компонент в Angular — это класс TypeScript, украшенный декоратором @Component
. Он имеет прикрепленный шаблон и таблицы стилей CSS, которые формируют представление компонента.
Angular 7, последняя версия Angular, была недавно выпущена с новыми функциями, особенно в инструментарии и производительности CLI, такими как:
- Подсказки CLI: общие команды, такие как
ng add
иng new
, теперь могут предлагать пользователю выбрать функции для добавления в проект, такие как маршрутизация, формат таблиц стилей и т. д. - Добавление прокрутки в Angular Material CDK (Component DevKit).
- Добавление поддержки перетаскивания в Angular Material CDK.
- Проекты также по умолчанию используют бюджетные пакеты, которые будут предупреждать разработчиков, когда их приложения превышают ограничения по размеру. По умолчанию предупреждения выдаются, когда размер превышает 2 МБ, а ошибки — 5 МБ. Вы также можете изменить эти ограничения в файле
angular.json
. и т.п.
Представляем угловой маршрутизатор
Angular Router — это мощный маршрутизатор JavaScript, созданный и поддерживаемый основной командой Angular, который можно установить из пакета @angular/router
. Он предоставляет полную библиотеку маршрутизации с возможностью иметь несколько выходов маршрутизатора, различные стратегии сопоставления путей, легкий доступ к параметрам маршрута и защиту маршрута для защиты компонентов от несанкционированного доступа.
Маршрутизатор Angular является основной частью платформы Angular. Это позволяет разработчикам создавать одностраничные приложения с несколькими представлениями и разрешать навигацию между этими представлениями.
Давайте теперь более подробно рассмотрим основные концепции Router.
Маршрутизатор-выход
Router-Outlet
— это директива, доступная в библиотеке маршрутизатора, где маршрутизатор вставляет компонент, который сопоставляется на основе URL-адреса текущего браузера. Вы можете добавить несколько выходов в свое приложение Angular, что позволит вам реализовать расширенные сценарии маршрутизации.
<router-outlet></router-outlet>
Любой компонент, который сопоставляется маршрутизатором, будет отображать его как одноуровневый элемент выхода маршрутизатора.
Маршруты и пути
Маршруты — это определения (объекты), состоящие как минимум из атрибутов пути и компонента (или пути перенаправления). Путь относится к части URL-адреса, которая определяет уникальное представление, которое должно отображаться, а компонент относится к компоненту Angular, который необходимо связать с путем. На основе определения маршрута, которое мы предоставляем (через статический RouterModule.forRoot(routes)
), Router может направить пользователя к определенному представлению.
Каждый Route
сопоставляет URL- path
с компонентом.
Путь может быть пустым, что обозначает путь приложения по умолчанию, и обычно это начало приложения.
Путь может содержать подстановочную строку ( **
). Маршрутизатор выберет этот маршрут, если запрошенный URL-адрес не соответствует ни одному из путей для определенных маршрутов. Это можно использовать для отображения представления «Не найдено» или для перенаправления на конкретное представление, если совпадение не найдено.
Это пример маршрута:
{ path: 'contacts', component: ContactListComponent}
Если это определение маршрута предоставлено в конфигурации маршрутизатора, маршрутизатор отобразит ContactListComponent
когда URL-адрес браузера для веб-приложения станет /contacts
.
Стратегии сопоставления маршрутов
Angular Router предоставляет различные стратегии сопоставления маршрутов. Стратегия по умолчанию заключается в простой проверке того, имеет ли URL-адрес текущего браузера префикс path .
Например, наш предыдущий маршрут:
{ path: 'contacts', component: ContactListComponent}
Можно также записать как:
{ path: 'contacts',pathMatch: 'prefix', component: ContactListComponent}
patchMath
определяет стратегию сопоставления. В этом случае это префикс , который используется по умолчанию.
Вторая стратегия сопоставления заполнена . Когда он указан для маршрута, маршрутизатор проверит, точно ли путь совпадает с путем URL-адреса текущего браузера:
{ path: 'contacts',pathMatch: 'full', component: ContactListComponent}
Параметры маршрута
Создание маршрутов с параметрами — обычная функция веб-приложений. Angular Router позволяет получить доступ к параметрам разными способами:
- Используя службу ActivatedRoute,
- Использование наблюдаемого объекта ParamMap, доступного, начиная с v4.
Вы можете создать параметр маршрута, используя синтаксис двоеточия . Это пример маршрута с параметром id :
{ path: 'contacts/:id', component: ContactDetailComponent}
Охранники маршрута
Защита маршрута — это функция Angular Router, которая позволяет разработчикам запускать некоторую логику при запросе маршрута и на основе этой логики разрешать или запрещать доступ пользователя к маршруту. Он обычно используется для проверки того, вошел ли пользователь в систему и имеет ли он авторизацию, прежде чем он сможет получить доступ к странице.
Вы можете добавить защиту маршрута, реализуя интерфейс CanActivate
, доступный в пакете @angular/router
, и расширяет метод canActivate()
, который содержит логику для разрешения или запрета доступа к маршруту. Например, следующая защита всегда разрешает доступ к маршруту:
class MyGuard implements CanActivate { canActivate() { return true; } }
Затем вы можете защитить маршрут с помощью Guard с помощью атрибута canActivate
:
{ path: 'contacts/:id, canActivate:[MyGuard], component: ContactDetailComponent}
Навигационная директива
Angular Router предоставляет директиву routerLink
для создания навигационных ссылок. Эта директива принимает путь, связанный с компонентом, к которому нужно перейти. Например:
<a [routerLink]="'/contacts'">Contacts</a>
Несколько выходов и вспомогательных маршрутов
Angular Router поддерживает несколько выходов в одном приложении.
Компонент имеет один связанный первичный маршрут и может иметь вспомогательные маршруты. Вспомогательные маршруты позволяют разработчикам перемещаться по нескольким маршрутам одновременно.
Для создания вспомогательного маршрута вам понадобится именованный выход маршрутизатора, где будет отображаться компонент, связанный с дополнительным маршрутом.
<router-outlet></router-outlet> <router-outlet name="outlet1"></router-outlet>
- Розетка без названия является основной.
- Все розетки должны иметь имя, кроме основной розетки.
Затем вы можете указать выход, в котором вы хотите отобразить свой компонент, используя атрибут выхода:
{ path: "contacts", component: ContactListComponent, outlet: "outlet1" }
Создание демонстрационного проекта Angular 7
В этом разделе мы увидим практический пример того, как настроить и работать с Angular Router. Вы можете увидеть живую демонстрацию, которую мы будем создавать, и репозиторий проекта на GitHub.
Установка Angular CLI v7
Для Angular CLI требуется Node 8.9+ с NPM 5.5.1+ . Вам необходимо убедиться, что в вашей системе установлены эти требования, а затем выполните следующую команду, чтобы установить последнюю версию Angular CLI:
$ npm install -g @angular/cli
Это установит Angular CLI глобально.
Примечание . Вы можете использовать sudo
для глобальной установки пакетов, в зависимости от вашей конфигурации npm.
Создание проекта Angular 7
Создать новый проект можно одной командой, вам просто нужно запустить следующую команду:
$ ng new angular7-router-demo
Интерфейс командной строки спросит вас, хотите ли вы добавить маршрутизацию (введите N
вместо «Нет», потому что мы увидим, как мы можем добавить маршрутизацию вручную) и какой формат таблицы стилей вы хотите использовать, выберите CSS, первый вариант, затем нажмите Enter
. CLI создаст структуру папок с необходимыми файлами и установит необходимые зависимости проекта.
Создание поддельной серверной службы
Поскольку у нас нет реальной серверной части, с которой можно взаимодействовать, мы создадим фальшивую серверную часть, используя библиотеку angular-in-memory-web-api
, которая представляет собой веб-API в памяти для демонстраций и тестов Angular, которые эмулирует операции CRUD через REST API.
Он работает, перехватывая запросы HttpClient
, отправленные на удаленный сервер, и перенаправляет их в локальное хранилище данных в памяти, которое нам нужно создать.
Чтобы создать поддельный сервер, нам нужно выполнить следующие шаги:
- Сначала мы устанавливаем модуль
angular-in-memory-web-api
, - Далее мы создаем сервис, который возвращает поддельные данные,
- Наконец, настройте приложение для использования фальшивой серверной части.
В терминале выполните следующую команду, чтобы установить модуль angular-in-memory-web-api
из npm:
$ npm install --save angular-in-memory-web-api
Затем создайте серверную службу, используя:
$ ng gs backend
Откройте файл src/app/backend.service.ts
и импортируйте InMemoryDbService
из модуля angular-in-memory-web-api
:
import {InMemoryDbService} from 'angular-in-memory-web-api'
Класс службы должен реализовать InMemoryDbService
а затем переопределить метод createDb()
:
@Injectable({ providedIn: 'root' }) export class BackendService implements InMemoryDbService{ constructor() { } createDb(){ let contacts = [ { id: 1, name: 'Contact 1', email: '[email protected]' }, { id: 2, name: 'Contact 2', email: '[email protected]' }, { id: 3, name: 'Contact 3', email: '[email protected]' }, { id: 4, name: 'Contact 4', email: '[email protected]' } ]; return {contacts}; } }
Мы просто создаем массив контактов и возвращаем их. Каждый контакт должен иметь идентификатор.
Наконец, нам просто нужно импортировать InMemoryWebApiModule
в файл app.module.ts
и предоставить нашу поддельную серверную службу.
import { InMemoryWebApiModule } from “angular-in-memory-web-api”; import { BackendService } from “./backend.service”; /* ... */ @NgModule({ declarations: [ /*...*/ ], imports: [ /*...*/ InMemoryWebApiModule.forRoot(BackendService) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Затем создайте ContactService
, который инкапсулирует код для работы с контактами:
$ ng gs contact
Откройте файл src/app/contact.service.ts
и обновите его, чтобы он выглядел примерно так:
import { Injectable } from '@angular/core'; import { HttpClient } from “@angular/common/http”; @Injectable({ providedIn: 'root' }) export class ContactService { API_URL: string = "/api/"; constructor(private http: HttpClient) { } getContacts(){ return this.http.get(this.API_URL + 'contacts') } getContact(contactId){ return this.http.get(`${this.API_URL + 'contacts'}/${contactId}`) } }
Мы добавили два метода:
-
getContacts()
Для получения всех контактов. -
getContact()
Для получения контакта по id.
Вы можете установить API_URL
на любой URL-адрес, поскольку мы не собираемся использовать настоящий сервер. Все запросы будут перехвачены и отправлены на серверную часть в памяти.
Создание наших компонентов Angular
Прежде чем мы сможем увидеть, как использовать различные функции маршрутизатора, давайте сначала создадим набор компонентов в нашем проекте.
Перейдите к своему терминалу и выполните следующие команды:
$ ng gc contact-list $ ng gc contact-detail
Это создаст два компонента ContactListComponent
и ContactDetailComponent
и добавит их в основной модуль приложения.
Настройка маршрутизации
В большинстве случаев вы будете использовать Angular CLI для создания проектов с настройкой маршрутизации, но в этом случае мы добавим его вручную, чтобы лучше понять, как маршрутизация работает в Angular.
Добавление модуля маршрутизации
Нам нужно добавить AppRoutingModule
, который будет содержать маршруты наших приложений и выход маршрутизатора, куда Angular будет вставлять текущий соответствующий компонент в зависимости от текущего URL-адреса браузера.
Посмотрим:
- Как создать модуль Angular для маршрутизации и импортировать его;
- Как добавлять маршруты к разным компонентам;
- Как добавить розетку роутера.
Во-первых, давайте начнем с создания модуля маршрутизации в файле app-routing.module.ts
. Внутри src/app
создайте файл, используя:
$ cd angular7-router-demo/src/app $ touch app-routing.module.ts
Откройте файл и добавьте следующий код:
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; const routes: Routes = []; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
Мы начинаем с импорта NgModule
из пакета @angular/core
, который представляет собой декоратор TypeScript, используемый для создания модуля Angular.
Также мы импортируем RouterModule
и Routes
из пакета @angular/router
. RouterModule
предоставляет статические методы, такие как RouterModule.forRoot()
, для передачи объекта конфигурации маршрутизатору.
Затем мы определяем постоянный массив routes
типа Routes
, который будет использоваться для хранения информации для каждого маршрута.
Наконец, мы создаем и экспортируем модуль с именем AppRoutingModule
(вы можете называть его как хотите), который представляет собой просто класс TypeScript, украшенный декоратором @NgModule
, который принимает некоторый объект метаинформации. В атрибуте imports
этого объекта мы вызываем статический RouterModule.forRoot(routes)
с массивом маршрутов в качестве параметра. В массив exports
добавляем RouterModule
.
Импорт модуля маршрутизации
Затем нам нужно импортировать маршрутизацию этого модуля в основной модуль приложения, который находится в файле src/app/app.module.ts
:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Мы импортируем AppRoutingModule
из ./app-routing.module
и добавляем его в массив imports
основного модуля.
Добавление розетки маршрутизатора
Наконец, нам нужно добавить розетку маршрутизатора. Откройте файл src/app/app.component.html
, содержащий основной шаблон приложения, и добавьте компонент <router-outlet>
:
<router-outlet></router-outlet>
Здесь Angular Router будет отображать компонент, соответствующий текущему пути браузера.
Это все шаги, которые нам нужно выполнить, чтобы вручную настроить маршрутизацию внутри проекта Angular.
Создание маршрутов
Теперь давайте добавим маршруты к нашим двум компонентам. Откройте файл src/app/app-routing.module.ts
и добавьте следующие маршруты в массив routes
:
const routes: Routes = [ {path: 'contacts' , component: ContactListComponent}, {path: 'contact/:id' , component: ContactDetailComponent} ];
Обязательно импортируйте два компонента в модуль маршрутизации:
import { ContactListComponent } from './contact-list/contact-list.component'; import { ContactDetailComponent } from './contact-detail/contact-detail.component';
Теперь мы можем получить доступ к двум компонентам из путей /contacts
и contact/:id
.
Добавление навигационных ссылок
Далее давайте добавим навигационные ссылки в наш шаблон приложения, используя директиву routerLink
. Откройте src/app/app.component.html
и добавьте следующий код поверх выхода маршрутизатора:
<h2><a [routerLink] = "'/contacts'">Contacts</a></h2>
Далее нам нужно отобразить список контактов в ContactListComponent
. Откройте src/app/contact-list.component.ts
и добавьте следующий код:
import { Component, OnInit } from '@angular/core'; import { ContactService } from '../contact.service'; @Component({ selector: 'app-contact-list', templateUrl: './contact-list.component.html', styleUrls: ['./contact-list.component.css'] }) export class ContactListComponent implements OnInit { contacts: any[] = []; constructor(private contactService: ContactService) { } ngOnInit() { this.contactService.getContacts().subscribe((data : any[])=>{ console.log(data); this.contacts = data; }) } }
Мы создаем массив contacts
для хранения контактов. Затем мы ContactService
и вызываем метод экземпляра getContacts()
(в событии жизненного цикла ngOnInit
), чтобы получить контакты и назначить их массиву contacts
.
Затем откройте файл src/app/contact-list/contact-list.component.html
и добавьте:
<table> <tr> <th>Name</th> <th>Email</th> <th>Actions</th> </tr> <tr *ngFor="let contact of contacts" > <td>{{ contact.name }}</td> <td>{{ contact.email }}</td> <td> <a [routerLink]="['/contact', contact.id]">Go to details</a> </td> </tr> </table>
Мы перебираем контакты и отображаем имя и адрес электронной почты каждого контакта. Мы также создаем ссылку на компонент сведений о каждом контакте, используя директиву routerLink
.
Это скриншот компонента:
Когда мы нажимаем ссылку « Перейти к деталям », мы попадаем в ContactDetailsComponent
. Маршрут имеет параметр id
, давайте посмотрим, как мы можем получить к нему доступ из нашего компонента.
Откройте файл src/app/contact-detail/contact-detail.component.ts
и измените код, чтобы он выглядел примерно так:
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { ContactService } from '../contact.service'; @Component({ selector: 'app-contact-detail', templateUrl: './contact-detail.component.html', styleUrls: ['./contact-detail.component.css'] }) export class ContactDetailComponent implements OnInit { contact: any; constructor(private contactService: ContactService, private route: ActivatedRoute) { } ngOnInit() { this.route.paramMap.subscribe(params => { console.log(params.get('id')) this.contactService.getContact(params.get('id')).subscribe(c =>{ console.log(c); this.contact = c; }) }); } }
Мы ContactService
и ActivatedRoute
в компонент. В событии жизненного цикла ngOnInit()
мы извлекаем параметр id , который будет передан из маршрута, и используем его для получения сведений о контакте, которые мы назначаем объекту contact
.
Откройте файл src/app/contact-detail/contact-detail.component.html
и добавьте:
<h1> Contact # {{contact.id}}</h1> <p> Name: {{contact.name}} </p> <p> Email: {{contact.email}} </p>
Когда мы впервые заходим в наше приложение с 127.0.0.1:4200/
, аутлет не отображает никаких компонентов, поэтому давайте перенаправим пустой путь на путь к contacts
, добавив следующий маршрут в массив маршрутов:
{path: '', pathMatch: 'full', redirectTo: 'contacts'}
Мы хотим сопоставить точный пустой путь, поэтому указываем стратегию полного совпадения.
Заключение
В этом руководстве мы увидели, как использовать Angular Router для добавления маршрутизации и навигации в наше приложение. Мы видели различные концепции, такие как выход маршрутизатора, маршруты и пути, и создали демонстрацию, чтобы на практике показать различные концепции. Вы можете получить доступ к коду из этого репозитория.