Параметры маршрута

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

Маршруты могут определять параметры, через которые мы можем передавать компоненту какие-то данные извне. Для примера возьмем проект из прошлой темы:

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

В папку src/app добавим новый файл item.component.ts с новым компонентом:

import { Component} from "@angular/core";
import { ActivatedRoute} from "@angular/router";
  
@Component({
    selector: "item-info",
    template: `<h2>Модель {{id}}</h2>`
})
export class ItemComponent { 
     
    id: number;
    constructor(private activateRoute: ActivatedRoute){
         
        this.id = activateRoute.snapshot.params["id"];
    }
}

Для получения параметров маршрута нам необходим специальный сервис ActivatedRoute. Он содержит информацию о маршруте, в частности, параметры маршрута, параметры строки запроса и прочее. Он внедряется в приложение через механизм dependency injection, поэтому в конструкторе мы можем получить его.

Свойство snapshot хранит состояние маршрута, а состояние маршрута содержит переданные параметры.

В данном случае мы предполагаем, что параметр будет называться "id", но это необязательно. Название параметра может быть любым.

Но пока нет никакого маршрута, который бы использовал данный компонент. Поэтому изменим определение маршрутов в файле app.config.ts:

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

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

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

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

Здесь добавлен новый маршрут

{ path: "item/:id", component: ItemComponent}

Токен :id представляет параметр маршрута. То есть мы сможем обратиться к компоненту с запросом типа /item/6, и число 6 будет представлять параметр id.

Теперь изменим главный компонент AppComponent:

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

@Component({
    selector: "my-app",
    standalone: true,
    imports: [RouterOutlet, RouterLink],
    template: `<div>
                    <nav>
                        <a routerLink="">Главная</a>
                        <a routerLink="/about">О сайте</a>
                        <a routerLink="/item/5">Item 5</a>
                    </nav>
                    <router-outlet></router-outlet>
               </div>`
})
export class AppComponent {}

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

<a routerLink="/item/5">Item 5</a>

И при запуске приложения мы сможем по ссылке обращаться к компоненту ItemComponent и передавать ему id=5:

Параметры маршрутов в Angular 17

Данный подход работает для одной ссылки, но что если у нас несколько ссылок на один и тот же компонент, но с разными id:

<a routerLink="/item/5">Item 5</a>
<a routerLink="/item/8">Item 8</a>

Если мы сначала перейдем по первой ссылке, то компонент ItemComponent получит id=5. Если после этого мы перейдем по второй ссылке, ItemComponent будет продолжать хранить прежнее значение id = 5.

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

import { Component} from "@angular/core";
import { ActivatedRoute} from "@angular/router";
import {Subscription} from "rxjs";
  
@Component({
    selector: "item-info",
    template: `<h2>Модель {{id}}</h2>`
})
export class ItemComponent { 
     
    id: number | undefined;
    private subscription: Subscription;
    constructor(private activateRoute: ActivatedRoute){
         
        this.subscription = activateRoute.params.subscribe(params=>this.id=params["id"]);
    }
}

Метод subscribe() позволяет установить подписку на изменение параметра маршрута. В этом случае компонент будет получать новое значение, и проблем с навигацией по ссылкам с разными параметрами не возникнет.

Для решения выше озвученной проблемы также есть и другое решение. Изменим ItemComponent следующим образом:

import { Component, OnInit} from "@angular/core";
import { ActivatedRoute} from "@angular/router";
import { switchMap } from "rxjs/operators";
  
@Component({
    selector: "item-info",
    template: `<h2>Модель {{id}}</h2>`
})
export class ItemComponent implements OnInit { 
      
    id: number | undefined;
     
    constructor(private route: ActivatedRoute){}
    ngOnInit() {
        this.route.paramMap.pipe(
            switchMap(params => params.getAll("id"))
        )
        .subscribe(data=> this.id = +data);
      }
}

В данном случае получение id происходит в методе ngOnInit. Для этого происходит обращение к свойству this.route.paramMap, которое представляет объект Observable<ParamMap> (ParamMap представляет карту параметров -как параметров маршрута, так и строки запроса). Далее у Observable вызывается метод pipe(), который позволяет создать цепочку операторов rxjs.

В методе pipe() вызывается оператор switchMap(), который в качестве параметра принимает функцию с одним параметром - ParamMap. Таким образом мы извлекаем карту параметров и берем из нее значение параметра id. При изменении значения параметра switchMap позволяет получить новое значение.

По умолчанию значение параметра id представляет строку, поэтому далее с помощью метода subcribe мы подписываемся на объект Observable и приналичии данных извлекаем значение id. Плюс перед значением +data указывает на преобразование к числу.

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