Parâmetros de Rotas em Angular
As rotas podem definir parâmetros que nos permitem passar dados para um componente a partir de fontes externas. Para ilustrar, vamos utilizar o projeto do tema anterior:
helloapp/ ├── src/ │ ├── app/ │ │ ├── about.component.ts │ │ ├── app.component.ts │ │ ├── app.config.ts │ │ ├── home.component.ts │ │ ├── not-found.component.ts │ ├── main.ts │ ├── index.html ├── angular.json ├── package-lock.json ├── package.json └── tsconfig.json
Dentro da pasta src/app, vamos adicionar um novo arquivo item.component.ts contendo o seguinte componente:
import { Component } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
@Component({
  selector: "item-info",
  template: `<h2>Modelo {{ id }}</h2>`,
})
export class ItemComponent {
  id: number;
  constructor(private activateRoute: ActivatedRoute) {
    this.id = activateRoute.snapshot.params["id"];
  }
}Para obter os parâmetros de rota, utilizamos o serviço ActivatedRoute, que contém informações sobre a rota, incluindo os parâmetros e outras propriedades, como query strings. Esse serviço é injetado na aplicação através do mecanismo de dependency injection, permitindo que o recebamos diretamente no construtor do componente.
A propriedade snapshot armazena o estado da rota e contém os parâmetros passados. Neste caso, esperamos que o parâmetro seja chamado "id", mas isso pode variar: o nome do parâmetro é flexível.
Agora precisamos definir uma rota que utilize este componente. Vamos modificar o arquivo 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)],
};Aqui, adicionamos uma nova rota:
{ path: "item/:id", component: ItemComponent }O token :id representa o parâmetro da rota. Isso significa que podemos acessar o componente através de uma URL como /item/6, onde o número 6 será passado como o parâmetro id.
Agora, vamos ajustar o componente principal AppComponent:
import { Component } from "@angular/core";
import { RouterOutlet, RouterLink } from "@angular/router";
@Component({
  selector: "my-app",
  standalone: true,
  imports: [RouterOutlet, RouterLink],
  styles: `
    a {
      padding: 5px;
    }
    `,
  template: `<div>
    <nav>
      <a routerLink="">Home</a>
      <a routerLink="/about">Sobre</a>
      <a routerLink="/item/5">Item 5</a>
    </nav>
    <router-outlet></router-outlet>
  </div>`,
})
export class AppComponent {}Ao definir um link para um componente que utiliza parâmetros de rota, todos os parâmetros necessários são inseridos diretamente na URL:
<a routerLink="/item/5">Item 5</a>Ao iniciar a aplicação, podemos acessar o componente ItemComponent e passar o id=5 através do link.

Problemas com Múltiplos Parâmetros de Rotas
Este método funciona bem para uma única rota, mas se tivermos vários links apontando para o mesmo componente com diferentes ids, como:
<a routerLink="/item/5">Item 5</a> 
<a routerLink="/item/8">Item 8</a>Se navegarmos primeiro para o link do Item 5, o componente ItemComponent receberá id=5. Contudo, ao clicar no segundo link, o componente continuará exibindo o valor id=5.
Para resolver esse problema, precisamos atualizar dinamicamente o valor de id dentro do componente. Vamos alterar o código do ItemComponent:
import { Component } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { Subscription } from "rxjs";
@Component({
  selector: "item-info",
  template: `<h2>Modelo {{ 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"]));
  }
}O método subscribe() permite que o componente reaja às mudanças nos parâmetros de rota, garantindo que ele receba o novo valor ao navegar para diferentes URLs.
Outra abordagem para resolver essa questão é utilizar o método ngOnInit no ItemComponent:
import { Component, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { switchMap } from "rxjs/operators";
@Component({
  selector: "item-info",
  template: `<h2>Modelo {{ 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));
  }
}Neste caso, o valor de id é obtido no método ngOnInit, onde acessamos a propriedade paramMap da rota, que representa um Observable<ParamMap> (um mapa de parâmetros de rota e query string). Utilizamos o método pipe() para aplicar operadores RxJS, como o switchMap(), que nos permite extrair o valor do parâmetro id e atualizá-lo dinamicamente.
Dessa forma, o componente consegue gerenciar corretamente diferentes parâmetros de rota ao longo da navegação.