Skip to content

GitLab

  • Menu
Projects Groups Snippets
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • A angular
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Monitor
    • Monitor
    • Metrics
    • Incidents
  • Packages & Registries
    • Packages & Registries
    • Package Registry
    • Infrastructure Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • imunnic
  • angular
  • Wiki
  • Modulo 3

Last edited by imunnic Dec 22, 2025
Page history

Modulo 3

Bloque 3 – Navegación y estructura de aplicación (Angular moderno)


Sesión 10 – Introducción al Router

Introducción teórica

En Angular moderno, la navegación en aplicaciones SPA se gestiona sin módulos, utilizando una configuración centralizada de rutas basada en objetos Routes. El Router sigue siendo el encargado de asociar rutas con vistas, pero ahora se apoya en componentes standalone y en la función provideRouter, lo que simplifica la arquitectura y reduce la complejidad inicial del proyecto.


Ejemplo: configuración básica del Router en Panacea

Archivo app.routes.ts:

import { Routes } from '@angular/router';

export const routes: Routes = [
  {
    path: 'recursos',
    loadComponent: () =>
      import('./recursos/recursos.component')
        .then(c => c.RecursosComponent)
  },
  {
    path: 'activaciones',
    loadComponent: () =>
      import('./activaciones/activaciones.component')
        .then(c => c.ActivacionesComponent)
  }
];

Configuración del router en main.ts:

import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter } from '@angular/router';
import { AppComponent } from './app/app.component';
import { routes } from './app/app.routes';

bootstrapApplication(AppComponent, {
  providers: [
    provideRouter(routes)
  ]
});

Sesión 11 – Navegación entre vistas

Introducción teórica

En aplicaciones Angular sin módulos, el componente raíz actúa como contenedor de navegación. El componente <router-outlet> indica dónde se renderiza la vista asociada a la ruta activa. La navegación puede realizarse de forma declarativa mediante routerLink o de forma programática usando el servicio Router. También se definen rutas por defecto y rutas comodín para mejorar la experiencia de navegación.


Ejemplo: navegación entre Recursos y Activaciones

Archivo app.component.ts:

import { Component } from '@angular/core';
import { RouterOutlet, RouterLink } from '@angular/router';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, RouterLink],
  template: `
    <nav>
      <a routerLink="/recursos">Recursos</a>
      <a routerLink="/activaciones">Activaciones</a>
    </nav>

    <router-outlet></router-outlet>
  `
})
export class AppComponent {}

Rutas por defecto y wildcard en app.routes.ts:

export const routes: Routes = [
  { path: '', redirectTo: 'recursos', pathMatch: 'full' },
  {
    path: 'recursos',
    loadComponent: () =>
      import('./recursos/recursos.component')
        .then(c => c.RecursosComponent)
  },
  {
    path: 'activaciones',
    loadComponent: () =>
      import('./activaciones/activaciones.component')
        .then(c => c.ActivacionesComponent)
  },
  { path: '**', redirectTo: 'recursos' }
];

Sesión 12 – Rutas con parámetros

Introducción teórica

Las rutas con parámetros permiten adaptar una vista al contexto, como mostrar el detalle de un recurso sanitario concreto. En Angular moderno, el servicio ActivatedRoute sigue siendo el mecanismo para acceder a parámetros de ruta y query params, manteniendo una API coherente con versiones anteriores.


Ejemplo: detalle de recursos en Panacea

Ruta con parámetro:

{
  path: 'recursos/:id',
  loadComponent: () =>
    import('./recursos/recursos.component')
      .then(c => c.RecursosComponent)
}

Navegación con parámetro desde una vista:

<a [routerLink]="['/recursos', recurso.id]">
  Ver recurso
</a>

Lectura del parámetro en el componente:

import { ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute) {}

ngOnInit() {
  const id = this.route.snapshot.paramMap.get('id');
}

Uso de query params para filtrar recursos:

this.router.navigate(['/recursos'], {
  queryParams: { estado: 'activo' }
});

Sesión 13 – Lazy loading y estructuración moderna

Introducción teórica

En Angular moderno, el lazy loading se realiza directamente a nivel de componente mediante loadComponent, sin necesidad de módulos intermedios. Este enfoque permite dividir la aplicación en áreas funcionales independientes, mejorando el rendimiento inicial y la mantenibilidad del código en aplicaciones grandes como Panacea.


Ejemplo: carga diferida de vistas

{
  path: 'activaciones',
  loadComponent: () =>
    import('./activaciones/activaciones.component')
      .then(c => c.ActivacionesComponent)
}

Separación lógica dentro de una vista (ejemplo en Activaciones):

{
  path: 'activaciones/:id',
  loadComponent: () =>
    import('./activaciones/activacion-detalle.component')
      .then(c => c.ActivacionDetalleComponent)
}

Este enfoque permite estructurar vistas complejas sin introducir módulos.


Sesión 14 – Guards y control de acceso

Introducción teórica

Angular moderno introduce guards funcionales, que sustituyen a las clases tradicionales y reducen el código necesario. Los guards permiten controlar el acceso a rutas y los resolvers facilitan la precarga de datos antes de mostrar una vista, manteniendo separada la lógica de navegación de la lógica de presentación.


Ejemplo: guard funcional con login mockeado

Servicio de autenticación simulado:

import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class AuthService {
  private logged = true;

  isLogged(): boolean {
    return this.logged;
  }
}

Guard funcional CanActivate:

import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AuthService } from './auth.service';

export const authGuard: CanActivateFn = () => {
  const auth = inject(AuthService);
  const router = inject(Router);

  if (auth.isLogged()) {
    return true;
  }

  router.navigate(['/recursos']);
  return false;
};

Uso del guard en rutas:

{
  path: 'activaciones',
  canActivate: [authGuard],
  loadComponent: () =>
    import('./activaciones/activaciones.component')
      .then(c => c.ActivacionesComponent)
}

Introducción a un resolver funcional:

import { ResolveFn } from '@angular/router';

export const recursosResolver: ResolveFn<string[]> = () => {
  return ['Recurso A', 'Recurso B'];
};

Aplicación del resolver:

{
  path: 'recursos',
  resolve: { datos: recursosResolver },
  loadComponent: () =>
    import('./recursos/recursos.component')
      .then(c => c.RecursosComponent)
}
Clone repository

Índice

  • Inicio
  • Módulo 1. Fundamentos y arranque del proyecto
    • Módulo 1.1 Angular
    • Módulo 1.2 Estructura
    • Módulo 1.2 Arquitectura y conceptos base
  • Módulo 2. Componentes y reutilización
  • Módulo 3. Navegación y estructura de aplicación
  • Módulo 4. Servicios y comunicación con backend
  • Módulo 5. Gestión de estado (Stores)