O que é Routing Angular? Veja agora
O que é Routing Angular?
Como configurar o projeto para Routes
Como navegar com o Router links?
Style no Router
Como navegar nas Routes automaticamente
Como lidar com erros 404
É uma maneira simples de navegar nas páginas do nosso app.
Tecnicamente não temos múltiplas páginas no Angular, apenas carregamos diferentes componentes, desta forma economizamos dados e fazemos a página parecer diferente.
Vamos criar 3 componentes e daremos os seguintes nomes "principal", "sobre" e "usuário" iremos usar o CLI para isso.
ng generate component principal
ng generate component sobre
ng generate component usuario
Vamos criar uma pequena lista para ficar mais fácil a navegação das "páginas".
<li><a href="#">Principal</a></li>
<li><a href="#">Usuário</a></li>
<app-principal></app-principal>
<app-sobre></app-sobre>
<app-usuario></app-usuario>
Se olharmos no browser vemos os três componentes já carregados e não é bem o que queremos agora, vamos carregar apenas um componente específico ao clicar no link.
A primeira coisa é criar um Array de URL para associar os caminhos aos componentes correspondentes.
No arquivo "app.routing.module.ts" iremos criar um array const chamada "appRoutes" do tipo Routes e assim também importaremos o "@angular/router".
const appRoutes: Routes = [];
SobreComponent,
UsuarioComponent,
O Array espera um objeto JavaScript com as URL path e os componentes correspondentes. Pra isso vamos usar as key "path" e "component".
{ path: '', component: PrincipalComponent }, // www.exemplo.com.br/
{ path: 'sobre', component: SobreComponent}, // www.exemplo.com.br/sobre
{ path: 'usuario',  component: UsuarioComponent }  // www.exemplo.com.br/usuario
O caminho com o path vazio é o nosso domínio padrão.
Não é suficiente apenas as rotas no Array, precisamos dizer ao Angular que esse array de rotas deve ser usado.
Vamos importar o RouterModule do "@angular/router".
Para registrar uma rota devemos usar o método "RouterModule.forRoot()" nos imports do @NgModule. Precisamos dar um argumento a esse método, que em nosso caso é o array com o nome de "appRoutes".
Para que isso funcione não iremos usar o seletor de componente, ao invés disso iremos usar o "router-outlet", que é um directiva que diz ao Angular que queremos mostrar apenas o componente que está disponível na URL.
Agora o nosso Angular sabe que deve apenas carregar o componente correspondente a rota de acesso.
Podemos ver que apenas o componente principal está carregado, porém a navegação não está funcionando, mas caso a gente digite manualmente a URL o componente já está funcionando.
Para fazer a navegação entre links precisamos vincular um event do link a um button ou imagem a uma rota.
Precisamos trocar o "href" para a diretiva "routerLink".
<a routerLink="/path/to/component">Link</a>
Podemos também colocar uma string de array com o nome das rotas com os parâmetros.
<a [routerLink]="['/path', '/to', '/component']">Link</a>
Para melhor entendimento vamos adicionar as duas maneiras dentro do nosso arquivo.
<li><a routerLink="/">Principal</a></li>
<li><a routerLink="/sobre">Sobre</a></li>
<li><a [routerLink]="['/usuario]">Usuario</a></li>
Agora sim nossos componentes somente são carregados aqueles que são correspondentes ao próprio caminho.
Angular também tem o "routerLinkActive" que é uma diretiva para estilizar nossos links ativados baseado na rota selecionada.
A diretiva recebe a classe CSS e é inserida no próprio link, imagem ou botão, ou um elemento encapsulado (wrapper).
<li><a routerLink="/path" routerLinkActive="active-class">Link</a></li>
// No wrapper
<li routerLinkActive="active-class"><a routerLink="/path">Link</a></li>
Vamos trabalhar com um CSS simples, que muda apenas o background dos elementos.
Neste caso podemos adicionar no arquivo "app.componente.css" ou usar o arquivo global "styles.scss".
Neste caso iremos optar pelo "styles.scss".
.link-active {
Agora é só colocar eles em nossos elementos.
<li routerLinkActive="link-active"><a routerLink="/">Principal</a></li>
<li routerLinkActive="link-active"><a routerLink="/sobre">Sobre</a></li>
<li routerLinkActive="link-active"><a [routerLink]="['/usuario]">Usuario</a></li>
Podemos ver que o estilo está sendo colocado nos links ativos. Porém temos um problema que a página Principal sempre está com o estilo. Isso porque a diretiva por padrão considera o link ativa caso ele esteja na URL.
Precisamos configurar a diretiva e para isso vamos usar o "routerLinkActiveOptions" no elemento que queremos configurar.
<li routerLinkActive="link-active" [routerLinkActiveOptions]="{exact:true}><a routerLink="/">Principal</a></li>
Setamos como true, pois assim especificamos para o Angular que só é considerado o link ativo caso ele realmente esteja no caminho exato.
Agora o link "principal" não é considerado ativo caso esteja em outras páginas.
Vamos a um exemplo, ao logar na aplicação automaticamente somos redirecionado a outra página.
Começaremos adicionando um botão de login em nosso componente chamado "principal".
<button (click)="onLogin()">Login</button>
Vamos imaginar que esse método de login faz toda a autenticação do usuário.
selector: 'app-principal,
templateUrl: './ principal.component.html',
styleUrls: ['./ principal.component.css']
export class PrincipalComponent implements OnInit {
// Autenticação
// Redireciona o usuário
this.router.navigate(['/user']);
No método "onLogin()" que será executado pelo nosso button, será usado o "navigate()" que especifica para onde será redirecionado o usuário.
Esse método leva Link Parameters array como argumento e cada segmento do "path" é separado por um elemento.
this.object.navigate(['/path', '/to', 'component']);
Vamos dizer que nosso componente "sobre" se torne um "Sobre Mim" com as informações e somente seja carregado no componente "usuario".
Podemos simplesmente aninhar o componente "sobre" dentro do componente "usuario". Ao invés de ser "/sobre", se tornará "/usuario/sobre".
Vamos fazer as configurações no arquivo "app.routing.module.ts".
{ path: '', component: PrincipalComponent },
{ path: 'user',
component: UsuarioComponent,
// www.exemplo.com.br/usuario/sobre
{ path: 'sobre', component: SobreComponent}
No exemplo acima o componente "usuario" será pai do "sobre".
O componente "sobre" será carregado no "usuario", vamos remover o link do nosso menu.
Vamos adicionar nossa "router-outlet" no componente "usuario".
Usario.componente.html:
<p>Usuario!</p>
Agora se formos para o caminho "/usuario/sobre" nosso componente será carregado. Porém só é possível carregar digitando o caminho e vamos resolver isso.
Para manter nosso exemplo simples, vamos adicionar o "routerLink" e imagine que o item do sub-menu acessa e permite o usuário editar as informações sobre ele.
<p>Usuário!</p>
<a routerLink="/usuario/sobre">Sobre</a>
Quando um usuário acessa uma rota inexistente ele recebe o erro 404, o que não quer dizer muito para o usuário. Vamos criar uma página customizada para lidar com esse tipo de situação.
Vamos começar criando nosso componente chamado "page-not-found".
ng g c page-note-found
Na view vamos mostrar uma mensagem padrão:
<p>Desculpe, essa página não existe.</p>
Vamos adicionar nossa rota.
{ path: 'usuario',
{ path: 'page-not-found', component: PageNotFoundComponent }
Agora vamos fazer a parte de redirecionar qualquer página que não exista para o nosso caminho "/page-not-found". Vamos usar a propriedade "redirectTo". A sintaxe é assim:
{ path: 'path-to', component: nome_componente }
{ path: 'path-from', redirectTo: 'path-to' }
{ path: 'page-not-found', component: PageNotFoundComponent },
{path: ' pagina-que-nao-existe ', redirectTo: 'page-not-found' }
No exemplo acima estamos redirecionando do "/pagina-que-nao-existe" para o nosso componente "/page-not-found".
Como é insano a gente especificar cada caminho não existente no mundo, vamos usar o wildcard (coringa) e assim o Angular sabe que qualquer caminho que não esteja em nosso array de rotas será redirecionado.
O operador do wildcard é "**" e a sintaxe ficaria desta forma:
{ path: '**', redirectTo: 'path-to' }
No app.routing.module.ts:
{ path: '**', redirectTo: 'page-not-found' }
Agora quando o usuário acessar alguma rota que não esteja em nosso array de rotas, será redirecionado para o nosso componente page-not-found.