Visão Geral da Estrutura do Projeto
Uma aplicação Angular típica com múltiplos componentes para gerenciamento de rotas e autenticação. Os componentes principais incluem:
- ComponenteRaiz
- ComponentePrincipal
- ComponenteCabecalho
- ComponenteMenuLateral
- ComponenteProduto
- ComponenteConteudo
- ComponenteDialogoPersonalizado
- ComponenteLivros
- ComponenteAluno
- ComponenteProfessor
- ComponenteBemVindo
- ComponenteAutenticacao
Layout do Componente Principal
<div class="container-grid">
<div class="cabecalho">
<app-cabecalho></app-cabecalho>
</div>
<div class="menu-lateral">
<app-menu></app-menu>
</div>
<div class="area-conteudo">
<app-conteudo></app-conteudo>
</div>
</div>
Componente Raiz
<router-outlet></router-outlet>
Componente Conteúdo com Rotas Filhas
<router-outlet></router-outlet>
Configuração de Rotas (arquivo rotas-principal.module.ts)
import { NgModule } from '@angular/core';
import { RouterModule, Rotas } from '@angular/router';
import { ComponentePrincipal } from './componentes/principal/principal.componente';
import { ComponenteCabecalho } from './componentes/cabecalho/cabecalho.componente';
import { ComponenteMenuLateral } from './componentes/menu/menu.componente';
import { ComponenteProduto } from './componentes/produto/produto.componente';
import { ComponenteConteudo } from './componentes/conteudo/conteudo.componente';
import { ComponenteAluno } from './componentes/aluno/aluno.componente';
import { ComponenteProfessor } from './componentes/professor/professor.componente';
import { ComponenteLivros } from './componentes/livros/livros.componente';
import { ComponenteBemVindo } from './componentes/bemvindo/bemvindo.componente';
import { ComponenteAutenticacao } from './componentes/autenticacao/autenticacao.componente';
import { ServicoGuardaAutenticacao } from './servicos/guarda-autenticacao.servico';
const rotas: Rotas = [
{ caminho: '', redirecionarPara: '/principal/conteudo/bemvindo', correspondencia: 'completa' },
{ caminho: 'autenticacao', componente: ComponenteAutenticacao },
{ caminho: 'principal', redirecionarPara: '/principal/conteudo/bemvindo', correspondencia: 'completa' },
{
caminho: 'principal', componente: ComponentePrincipal,
filhos: [
{ caminho: 'cabecalho', componente: ComponenteCabecalho },
{ caminho: 'menu', componente: ComponenteMenuLateral },
{
caminho: 'conteudo', componente: ComponenteConteudo,
filhos: [
{ caminho: '', redirecionarPara: '/principal/conteudo/bemvindo', correspondencia: 'completa' },
{ caminho: 'bemvindo', componente: ComponenteBemVindo },
{ caminho: 'produto', componente: ComponenteProduto, canActivate: [ServicoGuardaAutenticacao] },
{ caminho: 'aluno', componente: ComponenteAluno },
{ caminho: 'livro', componente: ComponenteLivros },
{ caminho: 'professor', componente: ComponenteProfessor }
]
}
]
},
{ caminho: '**', redirecionarPara: 'autenticacao' }
];
@NgModule({
importacoes: [RouterModule.forRoot(rotas)],
exportacoes: [RouterModule]
})
export class RotasPrincipalModule { }
Implementação do Serviço Guarda de Navegação
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ServicoGuardaAutenticacao implements CanActivate {
constructor(private roteador: Router) { }
canActivate(
proximo: ActivatedRouteSnapshot,
estado: RouterStateSnapshot
): boolean | Observable<boolean> | UrlTree | Promise<boolean | UrlTree> {
const autenticado = localStorage.getItem('dados_login');
if (!autenticado) {
this.roteador.navigate(['/autenticacao']);
return false;
}
return true;
}
}
Componente de Autenticacao - Template HTML
<div class="formulario-login">
<div class="campos">
<div class="campo">
<label for="nomeUsuario"></label>
<span class="icone-entrada">
<i class="pi pi-user"></i>
<input type="text" id="nomeUsuario" placeholder="Nome de usuário" [(ngModel)]="nomeUsuario"/>
</span>
<small *ngIf="!nomeUsuario" class="erro">Nome de usuário obrigatório</small>
</div>
<div class="campo">
<label for="senha"></label>
<span class="icone-entrada">
<i class="pi pi-lock"></i>
<input type="password" id="senha" [(ngModel)]="senha" placeholder="Senha"/>
</span>
<small *ngIf="!senha" class="erro">Senha obrigatória</small>
</div>
<div class="botoes">
<button type="button" (click)="efetuarLogin()">Entrar</button>
</div>
</div>
</div>
<p-toast posicao="topo-centro"></p-toast>
Lógica do Componente de Autenticação (TypeScript)
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { ServicoMensagens } from 'primeng/api';
@Component({
seletor: 'app-autenticacao',
templateUrl: './autenticacao.componente.html',
styleUrls: ['./autenticacao.componente.scss'],
provedores: [ServicoMensagens]
})
export class ComponenteAutenticacao implements OnInit {
nomeUsuario: string;
senha: string;
constructor(
private roteador: Router,
private servicoMensagem: ServicoMensagens
) {
this.nomeUsuario = '';
this.senha = '';
}
ngOnInit(): void { }
efetuarLogin() {
if (this.nomeUsuario === 'admin' && this.senha === 'senha123') {
const informacoesLogin = { usuario: this.nomeUsuario, chave: this.senha };
localStorage.setItem('dados_login', JSON.stringify(informacoesLogin));
this.roteador.navigate(['/principal/conteudo']);
} else {
this.servicoMensagem.add({ severidade: 'erro', resumo: 'Erro', detalhe: 'Credenciais inválidas' });
}
}
}
Validação do Fluxo de Rotas
Ao tentar acessar a rota principal/conteudo/produto sem autanticação, o usuário é redirecionado para a página de login. Após inserir as credenciais corretas, a rota torna-se acessível. Removendo os dados do localStorage e atualizando a página, o redirecionamento ocorre novamente, confirmando o funcionamento do guarda de navegação.