Rotas no Angular
Rotas no Angular permite transformar componentes em páginas com URL, as rotas liberam o potencial do SPA (single page aplication), permitindo relacionar as URL’s do site e os componentes.
No Angular 17, devido o uso padrão da aplicação standalone, a forma de criar rotas mudou, aqui estará explicado a nova forma de criar rotas, posteriormente terá uma seção para o route.module a antiga forma de criar rotas.
Na hora do criar uma nova aplicação Angular na versão 17 ou superior, a CLI pergunta se já quer incluir os arquivos de configuração de rotas, respondendo sim, já virá tudo pronto para incluir as rotas da aplicação.
Configuração de arquivo de rotas
A configuração das rotas, em uma aplicação inicial, na versão 17 ou superior do Angular, se dará por dois arquivos, o app.config.ts e o app.routes.ts , no app.routes.ts estará o array de rotas da aplicação, e no app.config.ts avisará a aplicação qual lista de rotas estará as rotas da aplicação.
//app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [provideRouter(routes)]
};
Basta exportar uma variável do tipo ApplicationConfig que inclui o providers contendo o array de rotas, esse é um arquivo boilerplate que já vem por padrão, não precisa se preocupar em entender ele por agora.
Criando rotas
Como dito, rotas serão componentes ligados a URL’s do site, o arquivo app.routes.ts conterá essa relação, esse arquivo precisa exportar um array do tipo Route que vem do @angular/router. Para configurar a rota, passamos um objeto que tem um path que é um string para o caminho da rota e um component que será o componente rederizado para essa rota.
Exemplo de Uso
export const routes: Routes = [
{path:'pg1', component:Pg1Component},
{path:'pg2/:id', component:Pg2Component},
{path:'', redirectTo:'/pg1', pathMatch:'full'},
{path:'**', component:Pg404Component}
];
Temos 4 rotas nessa array e explicaremos cada uma por vez.
Primeira Rota
{path:'pg1', component:Pg1Component}
Nessa rota, estamos dizendo o caminho da url para acessa-la (urldosite.com/pg1) e ao acessar essa rota o usuário verá o componente Pg1Component.
Segunda Rota
{path:'pg2/:id', component:Pg2Component}
O que muda nessa segunda rota é que a URL aguarda um parâmetro depois do pg2, no Angular a declaração desse parâmetro é dois pontos e o nome do parâmetro :param, dentro do componente é possível resgatar essa informação pelo nome do parâmetro. Esse tipo de path é usado para rotas dinâmicas, como página de usuário, página de um produto, que depende do identificador daquela unidade. Um exemplo dessa URL é urldosite.com/pg2/2, nesse caso, id = 2.
Terceira Rota
{path:'', redirectTo:'/pg1', pathMatch:'full'}
Essa rota é uma rota de redirecionamento, sempre que eu acessar o site com path vazio (urldosite.com) o Angular me redirecionará para urldosite.com/pg1. pathMatch:'full' é necessário nesse caso, porque o caminho precisa ser exatamente o descrito.
Quarta Rota
{path:'**', component:Pg404Component}
o valor de path '**' é um valor coringa que significa qualquer rota, isso é interessante para quando o usuário acessar uma rota que não exista no nosso site, ser possível mostrar para ele uma página de erro 404, que significa página não encontrada. É importante que essa rota seja a última rota do array, pois quando nenhuma outra rota corresponder com o que o usuário acessou, esta página será mostrada.
RouterOutlet
No template do seu componente principal, adicione o RouterOutlet para indicar onde os componentes correspondentes às rotas devem ser renderizados.
<router-outlet></router-outlet>
Rotas alinhadas (children)
É comum ver em sites URL’s complexas com vários subpaths por exemplo: urldosite.com/user/details/13 no angular, podemos fazer isso através da propriedade children da configuração das rotas.
Exemplo de Uso
const routes: Routes = [
{
path: 'dashboard',
component: DashboardComponent,
children: [
{ path: 'profile', component: ProfileComponent },
{ path: 'settings', component: SettingsComponent },
// ... outras rotas filhas ...
]
},
// ... outras rotas principais ...
];
Dessa forma, para acessar o componente profile, eu preciso acessar o caminho dashboard/profile que pode continuar indefinidamente, caso eu queira que o profile também será um subpath basta incluir outra propriedade children nele e definir a rota.
Layout padrão
Com isso, é possível fazer layouts personalizados para cada tipo de rota. Suponha que na sua página tenha um header que é usado em todas as páginas da sua aplicação com exceção de algumas em especifico, como a rota de login, cadastro e a de erro, é possível separar essas rotas usando o children, segue o passo a passo:
-
Criar um Layout com Header:
Crie um componente que contenha o header e um
<router-outlet>para renderizar o conteúdo das rotas. Por exemplo,layout-com-header.component.html.<!-- layout-com-header.component.html --> <header> <!-- Conteúdo do header --> </header> <router-outlet></router-outlet> -
Configurar as Rotas:
No arquivo de configuração de rotas (
app-routing.module.ts), defina o layout com header como o componente principal para a maioria das rotas.const routes: Routes = [ { path: '', component: LayoutComHeaderComponent, // Layout com header para a maioria das rotas children: [ { path: 'pagina1', component: Pagina1Component }, { path: 'pagina2', component: Pagina2Component }, // ... outras rotas com header ... ] }, { path: 'login', component: LoginComponent }, // Rota sem header { path: 'logout', component: LogoutComponent }, // Rota sem header { path: '404', component: NotFoundComponent }, // Rota sem header ];Defina o layout com header como o componente principal para a maioria das rotas e, em seguida, adicione rotas específicas que não precisam do header (como login, logout e a página de erro 404) fora do layout com header.
-
Renderizar Rotas Sem Header:
Para as rotas que não precisam do header, o conteúdo será renderizado diretamente na
<router-outlet>sem o header presente.
Sua aplicação terá layouts personalizados para cada página, e também será possível incluir mais elementos de layout em componentes seguindo a mesma lógica.
RouterLink
A diretiva de atributo RouterLink pode ser adicionado a uma tag a seguido do caminho que o usuário será redirecionado ao clicar nesse elemento. O caminho precisa está dentro de colchetes em formato string.
Exemplo de Uso
<a [routerLink]="['/home']">Home</a>
<a [routerLink]="['/about']">About</a>
RouterLinkActive
Uma diretiva em Angular usada para aplicar uma classe CSS a um elemento HTML quando a rota associada estiver ativa ou corresponder à URL atual. Essa diretiva é útil para destacar visualmente o link ativo em menus de navegação ou para aplicar estilos específicos a um link quando sua rota estiver ativa.
Exemplo de Uso:
Suponha que você tenha um menu de navegação e deseja destacar visualmente o link ativo.
<nav>
<a routerLink="/home" routerLinkActive="link-ativo">Home</a>
<a routerLink="/about" routerLinkActive="link-ativo">Sobre</a>
</nav>
No exemplo acima: routerLinkActive="link-ativo" indica que a classe link-ativo deve ser aplicada ao elemento <a> quando a rota correspondente estiver ativa.
Router
É um serviço que providencia navegação entre URL e manipula ou extrai os elementos associados a rota. Como um serviço, é necessário injeta-lo no componente através do construtor.
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent {
constructor(
private router: Router
) { }
}
navigate
navigate é um método do serviço Router que permite redirecionar o usuário para outra rota.
this.router.navigate(['/login']);
this.router.navigate(['/user/details', userId]);
cada posição do array é um caminho separado pelo “/”. No segundo exemplo, o caminho é /user/details/1 se userId for igual a 1. As demais funcionalidades que o Router disponibiliza podem ser encontrados na documentação oficial.
ActivatedRoute
Para resgatar parâmetros no angular, usamos o serviço ActivatedRoute acessando .snapshot.paramMap.get e inserindo o nome do parâmetro.
import { Component, OnInit }from '@angular/core';
import { ActivatedRoute }from '@angular/router';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent {
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit() {
const paramId = this.activatedRoute.snapshot.paramMap.get('id');
}
}
O Activated Route nos dá acesso a rota ativa no momento, seus parâmetros e demais valores.
Caso o valor desse parâmetro altera sem recarregar a pagina, podemos obter ele em tempo real via um subscribe.
this.route.params.subscribe(params => {
const id = params['id'];
// Lógica para lidar com o parâmetro 'id'
});
As demais funcionalidades que o Activated Route disponibiliza podem ser encontrados na documentação oficial.