El concepto de rutas o routes se refiere a la capacidad de definir diferentes vistas o componentes correspondientes a diferentes rutas de URL en una aplicación de una sola página (SPA).
¿Te está gustando esta lección?
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
Esto permite a los usuarios navegar por la aplicación cambiando la URL y ver diferentes partes de la interfaz de usuario sin recargar la página.
Conceptos clave de routes
Routes: Es una colección de objetos Route
que definen cómo el router debe navegar entre diferentes vistas de la aplicación. Cada Route
es un objeto que contiene propiedades clave como path
, component
, redirectTo
, y otras configuraciones avanzadas.
Route Parameters: Las rutas pueden incluir parámetros que permiten a la aplicación ser más dinámica. Estos parámetros pueden ser opcionales o requeridos y se utilizan para pasar información a los componentes.
Nested Routes: Angular permite definir rutas anidadas, donde una ruta padre puede tener rutas hijas que se representan dentro del contexto del componente padre.
Lazy Loading: Las rutas pueden configurarse para cargar módulos de manera diferida (lazy loading), lo que mejora el rendimiento al cargar solo los módulos necesarios en lugar de toda la aplicación al inicio.
Guards: Las guardias son servicios que implementan interfaces específicas para controlar el acceso a las rutas. Existen diferentes tipos de guardias como CanActivate
, CanActivateChild
, CanDeactivate
, Resolve
, y CanLoad
.
Configuración de routes
Las rutas en Angular se definen como una matriz de objetos que describen las rutas y sus componentes asociados.
A partir de Angular 17, la configuración de rutas puede hacerse sin un módulo explícito, lo que simplifica la configuración de enrutamiento en las aplicaciones.
Para configurar las rutas en Angular, primero se define un arreglo de rutas (Routes
), y luego se pasa este arreglo al método RouterModule.forRoot
(para configuraciones en la raíz de la aplicación) o RouterModule.forChild
(para módulos secundarios).
Ejemplo de configuración de rutas:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: '**', component: PageNotFoundComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
En este ejemplo:
- La ruta
''
redirige a/home
utilizandoredirectTo
ypathMatch: 'full'
. - La ruta
/home
carga el componenteHomeComponent
. - La ruta
/about
carga el componenteAboutComponent
. - La ruta
**
actúa como un comodín que captura cualquier ruta no definida, mostrando un componente de página no encontrada (PageNotFoundComponent
).
Parámetros de ruta
Las rutas pueden aceptar parámetros, lo que permite a la aplicación ser más dinámica y flexible. Los parámetros pueden ser necesarios para ciertas rutas y se utilizan para pasar datos al componente correspondiente.
Ejemplo de parámetros de ruta:
const routes: Routes = [
{ path: 'article/:id', component: ArticleComponent }
];
Para acceder a los parámetros dentro del componente:
import { ActivatedRoute } from '@angular/router';
@Component({
// ...
})
export class ArticleComponent implements OnInit {
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route.paramMap.subscribe(params => {
const articleId = params.get('id');
// Lógica para manejar el artículo basado en el ID
});
}
}
Rutas anidadas
Las rutas anidadas permiten que una ruta padre tenga rutas hijas que se representan dentro del contexto del componente padre. Esto es útil para organizar la navegación de manera jerárquica.
Ejemplo de rutas anidadas:
const routes: Routes = [
{
path: 'dashboard',
component: DashboardComponent,
children: [
{ path: 'profile', component: ProfileComponent },
{ path: 'settings', component: SettingsComponent }
]
}
];
Carga diferida (Lazy Loading)
Angular soporta la carga diferida de módulos, lo que mejora el rendimiento de la aplicación al cargar solo los módulos necesarios en lugar de toda la aplicación al inicio.
Ejemplo de carga diferida:
const routes: Routes = [
{ path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) }
];
En este ejemplo, el módulo FeatureModule
solo se cargará cuando el usuario navegue a la ruta /feature
.
Guardias de ruta
Las guardias son servicios que implementan interfaces específicas y pueden ser usadas para controlar el acceso a las rutas. Las guardias más comunes son CanActivate
y CanLoad
.
Usando la interfaz CanActivate
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(): boolean {
if (this.authService.isLoggedIn()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}
Y en la configuración de rutas:
const routes: Routes = [
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }
];
Usando una función como guard
A partir de Angular 15, se pueden usar funciones en lugar de servicios que implementen interfaces.
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(): boolean {
if (this.authService.isLoggedIn()) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}
Y en la configuración de rutas:
const routes: Routes = [
{ path: 'dashboard', component: DashboardComponent, canActivate: [authGuardFn] }
];
Diferencias entre la interfaz y la función
- Interfaz CanActivate
: Es más adecuada cuando se necesita encapsular lógica compleja dentro de un servicio. Es útil para reusar la lógica de guardia en diferentes rutas y cuando se requiere dependencia de inyección de dependencias (DI) en el constructor del servicio.
- Función CanActivateFn
: Es más sencilla y directa. Ideal para casos donde la lógica de la guardia es simple y no se necesita reutilizar en múltiples rutas. También es útil para evitar la creación de servicios innecesarios.
Resolver datos
Los resolvers permiten obtener datos antes de que una ruta se active, asegurando que el componente tenga todos los datos necesarios al cargar.
Usando la interfaz Resolve
import { Injectable } from '@angular/core';
import { Resolve } from '@angular/router';
import { Observable } from 'rxjs';
import { DataService } from './data.service';
@Injectable({
providedIn: 'root'
})
export class DataResolver implements Resolve<Observable<any>> {
constructor(private dataService: DataService) {}
resolve() {
return this.dataService.getData();
}
}
Y en la configuración de rutas:
const routes: Routes = [
{ path: 'data', component: DataComponent, resolve: { data: DataResolver } }
];
Usando una función como resolver
import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { DataService } from './data.service';
export const dataResolverFn: ResolveFn<Observable<any>> = (route, state) => {
const dataService = inject(DataService);
return dataService.getData();
};
Y en la configuración de rutas:
const routes: Routes = [
{ path: 'data', component: DataComponent, resolve: { data: dataResolverFn } }
];
Diferencias entre la interfaz y la función
- Interfaz Resolve
: Al igual que con las guardias, es adecuada para encapsular lógica compleja de resolución de datos dentro de un servicio. Es útil cuando se requiere una configuración más estructurada y reutilizable.
- Función ResolveFn
: Proporciona una manera más sencilla y directa de definir resolvers. Es ideal para casos donde la lógica es simple y no se necesita reutilización extensa.
Módulos internos y principal
En Angular, la configuración de rutas se realiza principalmente a través de dos tipos de módulos: el módulo principal y módulos específicos para diferentes partes de la aplicación.
Módulo principal
En este módulo se definen las rutas raíz de la aplicación.
Se importa el módulo RouterModule
desde @angular/router
y se utiliza el método estático forRoot()
para proporcionar la configuración de las rutas.
Ejemplo de módulo principal:
// src/app/app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home.component';
import { AboutComponent } from './about.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent }
];
@NgModule({
declarations: [HomeComponent, AboutComponent],
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppModule { }
En este ejemplo:
- Se configuran dos rutas: la ruta de inicio (representada por una cadena vacía) y la ruta "about".
- Cada ruta está asociada a un componente que se mostrará cuando se navegue a la ruta.
Módulos internos
Las partes específicas de la aplicación pueden tener sus propios módulos y rutas. En estos módulos, se importa RouterModule
y se utiliza el método forChild()
para definir rutas específicas.
Ejemplo de módulo interno:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ProductsComponent } from './products.component';
import { ProductDetailComponent } from './product-detail.component';
const routes: Routes = [
{ path: 'products', component: ProductsComponent },
{ path: 'product/:id', component: ProductDetailComponent }
];
@NgModule({
declarations: [ProductsComponent, ProductDetailComponent],
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ProductsModule { }
Aprendizajes de esta lección
- Comprender el concepto de rutas (
Routes
) en Angular - Aprender a configurar rutas en Angular.
- Conocer el módulo principal y módulos internos y aprender a configurarlos.
- Aprender a implementar la navegación entre rutas.
- Implementar guardias y resolvers en rutas.
Completa Angular y certifícate
Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs