Angular-Loiane-Training

Este repositorio contem exemplos documentados e descricoes dos conteudos estudados ao longo do curso de Angular da Loiane

View project on GitHub

Guarda Rotas: CanDeactivate com Interface Generica

Ao utilizar o guarda rotas CanDeactivate e necessario que o tipo do component que sera verificado ao desativar a rota, imagine uma situacao onde varios components possuem a mesma logica de desativacao, nao seria uma boa pratica implementar um guarda rotas para cada component (afinal isso iria contra o reaproveitamento de codigo, um do principios por tras da orientacao o objetos).

deste modo, podemos criar uma interface que possui os metodos que devem ser implementados nos components para realizar a verificacao (lembre-se que na assinatura do metodo canDeactivate existe o parametro com o tipo do component passado como argumento na variavel de tipo da interface CanDeactivate

  • Exemplo de Interface
export interface IComponentsDeactivate {

  podeDesativar: boolean

  get desativar(): boolean

  set mudou(value: boolean)
}
  • Guarda Rotas

note que o que a variavel de tipo recebe o tipo da interface, ou seja, qualquer component que a implemente pode utilizar este guarda rotas, pois, ira possuir a implementacao dos metodos da interface.

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanDeactivate, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { IComponentsDeactivate } from './../general-interfaces/i-components-deactivate';

@Injectable({
  providedIn: 'root'
})
export class AlunosDeactivateGuard implements CanDeactivate<IComponentsDeactivate> {

  canDeactivate(_component: IComponentsDeactivate, _currentRoute: ActivatedRouteSnapshot, _currentState: RouterStateSnapshot, _nextState?: RouterStateSnapshot | undefined): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
    console.log('guarda de desativacao da rota')
    return _component.podeDesativar
  }
}
  • AlunosFormComponent

em nosso component iremos implementar a interface

import { Subscription } from 'rxjs';
import { AlunosService } from './../alunos.service';
import { ActivatedRoute } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { IComponentsDeactivate } from 'src/app/_06-rotas/general-interfaces/i-components-deactivate';

@Component({
  selector: 'app-alunos-form',
  templateUrl: './alunos-form.component.html',
  styleUrls: ['./alunos-form.component.css']
})
export class AlunosFormComponent implements OnInit, IComponentsDeactivate {

  public aluno: any
  private inscricao: Subscription
  podeDesativar: boolean = true; // implementacao da interface

  constructor(private _route: ActivatedRoute, private _service: AlunosService) { }

  ngOnInit(): void {
    this.inscricao = this._route.params.subscribe((params) => {
      this.aluno = this._service.getAluno(params['id'])
    })
  }

  ngOnDestroy(): void {
    this.inscricao.unsubscribe()
  }

  // implementacao da interface
  get desativar(): boolean {
    return this.desativar;
  }

  // implementacao da interface
  set mudou(value: boolean) {
    this.podeDesativar = value;
  }

}
  • template HTML de AlunosFormComponent

vamos utilizar o propertyBindind para realizar a chamada do metodo mudou, desse modo a variavel podeDesativar ira receber o valor true (o Angular e inteligente para atribuir o valor true como argumento)


<h5>
  Criar/Editar Aluno
</h5>

<div class="col s12">
  <div class="row">
    <div class="col s12">
      <label for="Id">#</label>
      <input disabled [(ngModel)]="aluno.id" id="id" type="text">
    </div>
  </div>
  <div class="row">
    <div class="col s12">
      <label for="nome" class="active">Nome</label>
      <!-- inclusao da propertyBindind (input)-->
      <input id="nome" [(ngModel)]="aluno.nome" type="text" (input)="mudou=false">
    </div>
  </div>
  <div class="row">
    <div class="col s12">
      <label for="email">Email</label>
      <!-- inclusao da propertyBindind (input)-->
      <input id="email" [(ngModel)]="aluno.email" type="email" (input)="mudou=false">
    </div>
  </div>
</div>

Note que ao realizar qualquer modificacao em um dos campos do formulario o guarda rotas CanDeactivate nao permite a saida da rota.


guarda rotas CanDeactivate.