Angular 22
Ejercicios de Angular sobre Router
7 ejercicios de Router en Angular. Piensa la respuesta antes de abrirla: la explicación dice por qué las demás opciones fallan.
1 · Elige la respuesta · nivel 1
¿Cómo se enlaza a /productos navegando con el router, sin recargar la página?
- A<a routerLink="/productos">Productos</a>
- B<a href="/productos">Productos</a>
- C<a router="/productos">Productos</a>
- D<a goto="/productos">Productos</a>
Ver la respuesta
Respuesta: A. <a routerLink="/productos">Productos</a>
routerLink le pide al router de Angular que cambie de vista sin pedir la página al servidor. Un href normal es válido en HTML, pero recarga toda la aplicación y pierde su estado.
2 · Completa el hueco · nivel 1
Completa el componente raíz para que Angular pinte aquí la página de la ruta activa.
<nav> <a routerLink="/">Inicio</a></nav><___ />- router-outlet
- ng-content
- ng-template
- router-view
Ver la respuesta
Respuesta: router-outlet
<nav> <a routerLink="/">Inicio</a></nav><router-outlet /><router-outlet> es el hueco donde el router muestra el componente de la ruta activa. ng-content sirve para proyectar contenido de un componente padre y router-view es de Vue, no de Angular.
3 · Elige la respuesta · nivel 2
¿Qué ocurre si el usuario no ha iniciado sesión?
export const authGuard: CanActivateFn = () => { const auth = inject(Auth); const router = inject(Router); return auth.isLoggedIn() || router.createUrlTree(['/login']);};- ARedirige a /login
- BBloquea la navegación y se queda en la página actual
- CLanza un error porque un guard debe devolver boolean
- DNavega a la ruta y después redirige
Ver la respuesta
Respuesta: A. Redirige a /login
Un guard puede devolver true, false o un UrlTree. Si devuelve un UrlTree, el router cancela la navegación y va a esa URL. Es mejor que llamar a router.navigate dentro del guard.
4 · Elige la respuesta · nivel 2
Con provideRouter(routes, withComponentInputBinding()), ¿cómo recibe el componente el :id de la ruta products/:id?
- ACon una entrada: id = input<string>()
- BSolo con inject(ActivatedRoute).snapshot.params
- CComo parámetro del constructor
- DCon el decorador @Param('id')
Ver la respuesta
Respuesta: A. Con una entrada: id = input<string>()
withComponentInputBinding pasa los parámetros de ruta, los query params y los datos de la ruta a las entradas del componente que tengan el mismo nombre. ActivatedRoute sigue funcionando, pero ya no hace falta.
5 · Encuentra el fallo · nivel 2
La ruta definida es 'producto/:id'. Uno de los dos enlaces lleva a una página 404. ¿Qué línea tiene el fallo?
1<ul>2 <li><a routerLink="/producto/7">Teclado</a></li>3 <li><a routerLink="/productos/9">Ratón</a></li>4</ul>Ver la respuesta
El fallo está en la línea 3:
<li><a routerLink="/productos/9">Ratón</a></li>Se arregla con<li><a routerLink="/producto/9">Ratón</a></li>.La ruta empieza por producto (en singular) y el segundo enlace usa productos. Los segmentos fijos deben coincidir letra por letra; solo :id acepta cualquier valor.
6 · Ordena las líneas · nivel 2
Ordena las rutas: inicio, detalle de producto y, al final, el comodín que redirige al inicio.
- { path: '', component: Home },
- { path: '*', redirectTo: '' },
- { path: '**', redirectTo: '' },
- { path: 'products/:id', component: ProductDetail },
- ];
- export const routes: Routes = [
Ver la respuesta
El orden correcto:
export const routes: Routes = [ { path: '', component: Home }, { path: 'products/:id', component: ProductDetail }, { path: '**', redirectTo: '' },];Sobran: { path: '*', redirectTo: '' },
El router prueba las rutas en orden y se queda con la primera que coincide, así que el comodín ** tiene que ir al final. Un solo * no es un comodín en Angular.
7 · Ordena las líneas · nivel 2
Ordena una ruta protegida y con carga diferida: primero la ruta, después el guard y al final la carga del componente.
- import('./admin/admin').then((m) => m.Admin),
- canActivate: [authGuard],
- loadComponent: () =>
- loadComponent: import('./admin/admin'),
- path: 'admin',
- {
- }
Ver la respuesta
El orden correcto:
{ path: 'admin', canActivate: [authGuard], loadComponent: () => import('./admin/admin').then((m) => m.Admin),}Sobran: loadComponent: import('./admin/admin'),
loadComponent recibe una función que devuelve el import dinámico: así el código solo se descarga al entrar en la ruta. Escribir el import directamente lo cargaría al arrancar. El guard se comprueba antes de descargar.