Sergio Hidalgo
Apasionado por la tecnología. Ninja Developer, FullStack, Adm Servidores, Profesor de Angular, Node, Phaser, Javascript. sergiohidalgocaceres@gmail.com https://www.facebook.com/groups/607163139705114/
Guards
Son clases que nos permiten proteger rutas.
Al igual que los servicios, los guards se declaran en un módulo.
<!-- app.module.ts -->
@NgModule({
...
providers: [AutenticacionGuard],
...
})Los Guards deben implementar alguna de las siguientes cuatro interfaces:
- CanActivate
- CanActivateChild
- CanDeactivate
- CanLoad
CanActivate
CanActivate: Protege una ruta
<!-- autenticacion.guard.ts -->
...
export class AutenticadoGuard implements CanActivate {
canActivate(
rutaActivaFoto: ActivatedRouteSnapshot,
historialEstados: RouterStateSnapshot):
Observable<boolean> | Promise<boolean> | boolean
{
return true
}
}<!-- app.module.ts -->
...
const rutas: Route[] = [
{
path: "libros",
component: LibrosListadoComponent,
canActivate: [AutenticacionGuard]
}
]CanActivateChild
CanActivateChild: Protege las rutas hijas
<!-- autenticacion.guard.ts -->
...
export class AutenticadoGuard implements CanActivateChild {
canActivateChild(
rutaActivaFoto: ActivatedRouteSnapshot,
historialEstados: RouterStateSnapshot):
Observable<boolean> | Promise<boolean> | boolean
{
return true
}
}<!-- app.module.ts -->
...
const rutas: Route[] = [
{
path: "libros",
component: LibrosListadoComponent,
canActivate: [AutenticacionGuard],
canActivateChild: [AutenticacionGuard],
children: [
{path: "edicion", component: LibrosEdicion}
]
}
]CanDeactivate
CanDeactivate: No protege rutas. Protege data no guardada.
<!-- guardado.guard.ts -->
...
interface canDeactivateComponent {
canDeactivateComponente: () => boolean
}
@Injectable()
export class GuardadoGuard implements CanDeactivate<canDeactivateComponent> {
canDeactivate(component: canDeactivateComponent): boolean {
if(component.canDeactivateComponente()){
if(confirm("Hay datos no salvados, ¿Quieres salvarlos?")){
return false
}
return true
}
return true
}
}<!-- app.module.ts -->
...
const rutas: Route[] = [
{
path: "libros",
component: LibrosListadoComponent,
canActivate: [AutenticacionGuard],
canActivateChild: [AutenticacionGuard],
children: [
{
path: "edicion",
component: LibrosEdicion,
canDeactivate: [GuardadoGuard]
}
]
}
]Enviando data a una ruta
<!-- app.module.ts -->
...
const rutas: Route[] = [
{
path: "libros",
component: LibrosListadoComponent,
data: {
mensaje: "Mensaje enviado al componente"
}
}
]Se enviada datos a un componente usando la propiedad "data"
<!-- libros-listado.component.ts -->
...
export class LibrosListadoComponent {
constructor(private rutaActiva: ActivatedRoute) {}
ngOnInit(){
const mensaje = this.rutaActiva.snapshot.data["mensaje"]
}
}Para leer "data" desde un componente se usa la ruta activa.
Resolve
Es una clase que nos permite cargar data antes de cargar el componente
<!-- app.module.ts -->
...
const rutas: Route[] = [
{
path: "libros",
component: LibrosListadoComponent,
resolve: {
info: DataResolve
}
}
]Se enviada datos a un componente usando la propiedad "resolve"
Al igual que los servicios y los guards, se declaran en un módulo.
<!-- app.module.ts -->
@NgModule({
...
providers: [DataResolve],
...
})...
export class DataResolve implements Resolve<any> {
resolve(
rutaActiva: ActivatedRouteSnapshot,
historialEstados: RouterStateSnapshot):
Observable<any> | Promise<any> | any {
return {usuario: "ABC"}
}
}Los Resolves implementan una interface que también se llama "Resolve"
<!-- libros-listado.component.ts -->
...
export class LibrosListadoComponent {
constructor(private rutaActiva: ActivatedRoute) {}
ngOnInit(){
const datos = this.rutaActiva.snapshot.data["info"]
}
}Para leer desde un "Resolve" se hace de manera similar a "Data".
useHash
"useHash" nos permite indicar si las rutas que aparecerán en el navegador usarán "#" o no.
Para indicar su uso, hay que agregarlo al manejador de rutas.
<!-- app.routing.module.ts -->
...
@NgModule({
...
imports: [
RouterModule.forRoot(rutas, {useHash: true})
]
...
})
...queryParamsHandling
"queryParamsHandling" sirve para indicar si los parámetros de querystring se mantienen o si se suman nuevos parámetros de querystring.
this.ruteador.navigate(
["libros", "edicion"],
{queryParamsHandling: "preserve"}
)
this.ruteador.navigate(
["libros", "edicion"],
{
queryParams: {nivel: "2"},
queryParamsHandling: "merge"
}
)Las promesas
Es una operación asíncrona que representa a un valor que puede estar disponible ahora, a futuro o nunca.
Las promesas se declaran como una instancia de la clase "Promise".
const promesa: Promise = new Promise((resolve, reject) => {
// Si la promesa se cumple
resolve()
// Si la promesa se rechaza
reject()
})Si una promesa se cumple, se ejecuta el método "then".
Si una promesa se rechaza, se ejecuta el método "catch".
promesa.then((respuesta)=> console.log(respuesta))
promesa.catch((error) => console.log(error))promesa
.then((respuesta)=> console.log(respuesta))
.catch((error) => console.log(error))Se puede simplificar de la siguiente manera:
Las promesas pueden ejecutarse independientemente, pero si es necesario ejecutar un proceso cuando todas se han cumplido, se usa "Promise.all".
const promesa1 = new Promise(...)
const promesa2 = new Promise(...)
Promise
.all([promesa1, promesa2])
.then([respuestas] => console.log(respuestas))
.catch(error => console.log(error))Observables
Ejecuta un proceso asíncrono como las promesas, pero se pueden ejecutar varias veces y además se pueden cancelar.
Los observables pertenecen a la programación reactiva.
Para usar un "Observable" hay que importarlo de la librería "rxjs".
...
import { Observable, Observer } from "rxjs"
...
export class LibroListado {
...
cadena: Observable<string>
ngOnInit(){
this.cadena= Observable.create(
(observador: Observer) => {
// Para enviar data
observador.next("texto")
// Para avisar de un error
observador.error("ocurrió un error")
// Cuando las tareas se cumplieron
observador.complete()
}
)
}
...
}
Para recibir las tres opciones posibles: data, error, completo, se usa el método "subscribe".
...
import { Observable, Observer } from "rxjs"
...
export class LibroListado {
...
ngOnInit() {
...
this.cadena.subscribe(
data => console.log(data),
error => console.log(error),
completo => console.log("completo")
)
}
...
}
By Sergio Hidalgo
¿Cómo protegemos a las rutas? Protección de entrada: CanActivate, CanActivateChild. Protección de carga: CanLoad. Protección de salida: CanDeactivate.
Apasionado por la tecnología. Ninja Developer, FullStack, Adm Servidores, Profesor de Angular, Node, Phaser, Javascript. sergiohidalgocaceres@gmail.com https://www.facebook.com/groups/607163139705114/