Sunteți pe pagina 1din 19

20/7/2019 Tutorial Angular – 7. Enrutamiento.

– Developing in Spanish

 DEVELOPING IN SPANISH

Tutorial Angular – 7. Enrutamiento.


 javfon1    13 marzo, 2018    No hay comentarios

Enrutamiento

Hemos recibido nuevos requisitos para nuestra aplicación Tour de Héroes.

Añadir un Cuadro de Mandos (dashboard).


Añadir la posibilidad de navegar entre el Cuadro de Mandos y la página de los héroes.
Cuando un usuario haga clic en cualquiera de las dos vistas, navegar a una vista de detalles del héroe
Cuando los usuarios hagan clic en un enlace profundo (deep link) en un correo, abre la vista de detalle
para un héroe en particular

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 1/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish

Cuando esté listo los usuarios serán capaces de navegar por la aplicación de este modo:

Añadir AppRoutingModule

Una buena práctica de Angular es cargar y con gurar el enrutador en un módulo separado y al nivel más alto,
que se dedique sólo al enrutamiento y que se importe en AppModule .
Por convenio, el nombre de este módulo es AppRoutingModule y pertence al chero app-routing.mo‐
dule.ts en la carpeta src/app .
Usaremos el CLI para generarlo.

ng generate module app-routing --flat --module=app

--flat deja el chero en src/app


en lugar de su propia carpeta.
--module=app le indica al CLI que lo registre en el array de imports de AppModule .

El chero generado debería ser así:

1 import { NgModule } from '@angular/core';


2 import { CommonModule } from '@angular/common';
3  
4 @NgModule({

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 2/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish
5   imports: [
6     CommonModule
7   ],
8   declarations: []
9 })
10 export class AppRoutingModule { }

En general, no se declaran componentes en un módulo de enrutamiento, así que podemos borrar el array
@NgModule.declarations y también CommonModule .
Con guraremos el enrutador con Routes en RouterModule así que importaremos estos dos símbolos de
la librería @angular/router .
Añade un array @NgModule.exports con RouterModel en él. Exportar RouterModule hace que las di-
rectivas de enrutamiento estén disponibles para los componentes de AppModule que lo necesiten.
AppRoutingModule quedaría así:

1 import { NgModule }             from '@angular/core';


2 import { RouterModule, Routes } from '@angular/router';
3  
4 @NgModule({
5   exports: [ RouterModule ]
6 })
7 export class AppRoutingModule {}

Añade rutas

Las rutas indican al enrutador que vistas mostrar cuando un usuario hace clic en un enlace o pegar una URL
en el navegador.
Un Route típico de Angular tiene dos propiedades:

1. path : una cadena que coincide con la URL del navegador.


2. component : el componete que el enrutador debe crear cuando navega a esta ruta.

La idea es navegar hasta HeroesComponent cuando la URL sea localhost:4200/heroes .


Importa HeroesComponent de modo que puedas referenciarlo en una Route . Después, de ne un array de
rutas con un único route a ese componente.

1 import { HeroesComponent }      from './heroes/heroes.component';


2  
3 const routes: Routes = [
4   { path: 'heroes', component: HeroesComponent }
5 ];

Una vez que hemos terminado esta con guración, el enrutador enlazará esa URL con path: 'heroes' y
mostrará HeroesComponent .

RouterModule.forRoot()

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 3/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish

Primero debemos inicializar el enrutador y empezar a escuchar los cambios del navegador.
Añade RouterModule al array @NgModule.imports y con guralo con routes en un solo paso llamando
a RouterModule.forRoot() dentro del array imports , tal que así:

1 imports: [ RouterModule.forRoot(routes) ],

El método se llama forRoot() porque el enrutador se cond gura al nivel raíz (root) de la aplicación.
El método forRoot() proporciona al servicio directivas y proveedores necesarios para el enrutamien-
to y realiza la navegación inicial basándose en la URL actual del navegador.

Añade RouterOutlet

Abre la plantilla de AppComponent y reemplaza el elemento <app-heroes> por el elemento <router-


outlet> .

1 <h1>{{title}}</h1>
2 <router-outlet></router-outlet>
3 <app-messages></app-messages>

Hemos eliminado <app-heroes> porque sólo mostraremos HeroesComponent cuando el usuario nave-
gue hasta él.
<router-outlet> le indica al enrutador donde mostrar las vistas enrutadas.

RouterOutlet es una de las directivas que están disponibles en AppComponent porque AppModule im-
porta AppRoutingModule, el cual exportó RouterModule.

Probando

Aún deberíamos estar ejecutando la aplicación con este comando del CLI.

 
    ng serve
 

El navegador debería actualizarse y mostrar el título de la aplicación pero no el listado de héroes.


Observa la barra de direcciones del navegador. La URL termina en / . La ruta a HeroesComponent es
/heroes .
Añade /heroes a la URL en la barra de direcciones. Deberías ver la ya conocida vista maestro/detalle de
héroes.

Añade un enlace de navegación (routerLink)

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 4/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish

Los usuarios no deberían pegar una URL en la barra de direcciones. Debería poder hacer clic en un enlace
para navegar.
Añade un elemento <nav> y dentro de él un elemento <a> que al hacer clic, accione la navegación a He‐
roesComponent . La plantilla AppComponent revisada quedaría así:

1 <h1>{{title}}</h1>
2 <nav>
3   <a routerLink="/heroes">Heroes</a>
4 </nav>
5 <router-outlet></router-outlet>
6 <app-messages></app-messages>

AL atributo routerLink se le asigna el valor /heroes , la cadena que el enrutador enlaza con la ruta a
HeroesComponent . routerLink es el selector para la directiva RouterLink que convierte los clics del
usuario en navegación del enrutador. Es otra de las directivas públicas dentro de RouterModule .
El navegador se actualiza y muestra el título de la aplicación y el enlace a héroes, pero no la lista de héroes.
Haz clic en el enlace. La barra de direcciones se actualiza a /heroes y la lista de héroes aparece.

Puedes conseguir que tanto este enlace como los siguientes tengan mejor aspecto añadiendo estilos CSS
privados a app.component.css , como verás en la revisión nal de código.

Añadir una vista para el Cuadro de Mandos

EL enroutamiento tiene más sentido cuando hay varias vistas. Por ahora, sólo tenemos la vista de héroes.
Añade un componente para el Cuadro de Mandos DashboardComponent usando el CLI:

 
    ng generate component dashboard
 

El CLI generará los archivos para DashboardComponent y lo declarará en AppModule.


Reemplaza el contenido por defecto de los cheros por los siguientes y ahora mismo los explicamos:

1 <h3>Top Heroes</h3>
2 <div class="grid grid-pad">
3   <a *ngFor="let hero of heroes" class="col-1-4">
4     <div class="module hero">
5       <h4>{{hero.name}}</h4>
6     </div>
7   </a>
8 </div>

1 import { Component, OnInit } from '@angular/core';


2 import { Hero } from '../hero';
3 import { HeroService } from '../hero.service';
4  
5 @Component({
6   selector: 'app-dashboard',
7   templateUrl: './dashboard.component.html',

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 5/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish
8   styleUrls: [ './dashboard.component.css' ]
9 })
10 export class DashboardComponent implements OnInit {
11   heroes: Hero[] = [];
12  
13   constructor(private heroService: HeroService) { }
14  
15   ngOnInit() {
16     this.getHeroes();
17   }
18  
19   getHeroes(): void {
20     this.heroService.getHeroes()
21       .subscribe(heroes => this.heroes = heroes.slice(1, 5));
22   }
23 }

1 /* DashboardComponent's private CSS styles */


2 [class*='col-'] {
3   float: left;
4   padding-right: 20px;
5   padding-bottom: 20px;
6 }
7 [class*='col-']:last-of-type {
8   padding-right: 0;
9 }
10 a {
11   text-decoration: none;
12 }
13 *, *:after, *:before {
14   -webkit-box-sizing: border-box;
15   -moz-box-sizing: border-box;
16   box-sizing: border-box;
17 }
18 h3 {
19   text-align: center; margin-bottom: 0;
20 }
21 h4 {
22   position: relative;
23 }
24 .grid {
25   margin: 0;
26 }
27 .col-1-4 {
28   width: 25%;
29 }
30 .module {
31   padding: 20px;
32   text-align: center;
33   color: #eee;
34   max-height: 120px;
35   min-width: 120px;
36   background-color: #607D8B;
37   border-radius: 2px;
38 }
39 .module:hover {
40   background-color: #EEE;
41   cursor: pointer;
42   color: #607d8b;
43 }
44 .grid-pad {
45   padding: 10px 0;
46 }
47 .grid-pad > [class*='col-']:last-of-type {

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 6/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish
48   padding-right: 20px;
49 }
50 @media (max-width: 600px) {
51   .module {
52     font-size: 10px;
53     max-height: 75px; }
54 }
55 @media (max-width: 1024px) {
56   .grid {
57     margin: 0;
58   }
59   .module {
60     min-width: 60px;
61   }
62 }

La plantilla presenta una cuadrícula (grid) de héroes con sus enlaces.

*ngFor crea tantos enlaces como haya en el array heroes del componente.
Los enlaces serán bloques de color, como indica dashboard.component.css
Los enlaces aún no llevan a ninguna parte, pero pronto lo harán.

La clase se parece a la clase de HeroesComponent .

De ne una propiedad array heroes .


El constructor espera que Angular inyecte HeroService en una propiedad privada heroService .
El ‘enganche de ciclo de vida’ (lifecycle hook) ngOnInit()
llama a getHeroes

getHeroes reduce el número de héroes mostrados a cuatro (2º, 3º, 4º y 5º).

1 getHeroes(): void {
2   this.heroService.getHeroes()
3     .subscribe(heroes => this.heroes = heroes.slice(1, 5));
4 }

Añade la ruta del Cuadro de Mandos

Para navegar al Cuadro de Mandos, el enrutador necesita una ruta apropiada.


Importa DashboardComponent en AppRoutingModule .

1 import { DashboardComponent }   from './dashboard/dashboard.component';

Añade una ruta al array AppRoutingModule.routes que enlaza una ruta al DashboardComponent .

1 { path: 'dashboard', component: DashboardComponent },

Añade una ruta por defecto

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 7/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish

Cuando la aplicación arranca, la barra de direcciones del navegador apunta a la raíz de la página web. Esto no
coincide con con ninguna ruta existente, así que el enrutador no navega a ninguna parte. El espacio debajo de
router-outlet está en blanco.
Para hacer que la aplicación navegue automáticamente al Cuadro de Mandos, añade la siguiente ruta al array
AppRoutingModule.Routes .

1 { path: '', redirectTo: '/dashboard', pathMatch: 'full' },

Esta ruta redirige una URL que coincide con el path vacío a la ruta del path '/dashboard' .
Cuando el navegador se actualiza, el enrutador carga DashboardComponent y la barra de direcciones mues-
tra la URL /dashboard .

Añade el enlace al Cuadro de Mandos al caparazón

El usuario debería ser capaz de navegar de ida y vuelta entre los componentes DashboardComponent y
HeroesComponent haciendo clic en los enlaces en el área de navegación en la parte de arriba de la página.
Añada un enlace de navegación al Cuadro de Mandos en la plantilla del caparazón AppComponent , justo so-
bre el enlace a Heroes.

1 <h1>{{title}}</h1>
2 <nav>
3   <a routerLink="/dashboard">Dashboard</a>
4   <a routerLink="/heroes">Heroes</a>
5 </nav>
6 <router-outlet></router-outlet>
7 <app-messages></app-messages>

Después de que el navegador se actualice puedes navegar libremente entre las dos vistas haciendo clic sobre
los enlaces.

Navegando a los detalles del héroe

HeroDetailsComponent muestra los detalles del héroe seleccionado. En este momento, code>HeroDetails-
Component sólo puede verse en la parte de abajo de code>HeroesComponent.
El usuario debería ser capaz de llegar a estos detalle de tres maneras:

1. Haciendo clic sobre un héroe en el Cuadro de Mandos.


2. Haciendo clic sobre un héroe en el listado de héroes.
3. Pegando un enlace profundo (deep link) en la barra de direcciones que identi que al héroe a mostrar.

En esta sección, activaremos la navegación a HeroeDetailsComponent y la eliminaremos de HeroesCom‐


ponent .

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 8/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish

Borrar los detalles del héroe de HeroesComponent

Cuando el usuario hace clic en un héroe en HeroesComponent , la aplicación debería navegar a HeroDe‐
tailComponent , reemplazando la vista del listado de héroes por la vista del detalle del héroe. EL listado de
héroes ya no debería mostrar detalles, tal y como hace ahora.
Abre la plantilla HeroesComponente (heroes/heroes.component.html) y borra el elemento <app-
hero-detail> del nal.
Hacer clic sobre un héroe ahora no hace nada. Arreglaremos esto pronto, después de activar el enrutamiento
a HeroDetailComponent .

Añade una ruta para el detalle del héroe

Una URL como ~/detail/11 sería una buena URL para navegar hasta la vista de detalle del héroe con id
igual a 11 .
Abre AppRoutingModule e importa HeroDetailComponent .

1 import { HeroDetailComponent }  from './hero-detail/hero-detail.component';

Después añade una ruta parametrizada al array AppRoutingModule.routes que coincida con el patrón de
la ruta a la vista del detalle del héroe.

1 { path: 'detail/:id', component: HeroDetailComponent },

Los dos puntos (:) en path indican que :id es un marcador de posición (placeholder) para un id concre-
to de héroe.
En este punto, todas las rutas de la aplicación están listas.

1 const routes: Routes = [


2   { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
3   { path: 'dashboard', component: DashboardComponent },
4   { path: 'detail/:id', component: HeroDetailComponent },
5   { path: 'heroes', component: HeroesComponent }
6 ];

Enlaces al héroe en el Cuadro de Mandos

Los héroes de HeroesComponent son elementos <li> cuyos eventos clic están vinculados al método
onSelect() de los componentes.

1 <ul class="heroes">
2   <li *ngFor="let hero of heroes"
3     [class.selected]="hero === selectedHero"
4     (click)="onSelect(hero)">
5     <span class="badge">{{hero.id}}</span> {{hero.name}}
6   </li>

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 9/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish
7 </ul>

Haz que <li> sólo use *ngFor , envuelve el badge y el nombre en un elemento <a> y añadele un atributo
RouterLink que es el mismo que en la plantilla del Cuadro de Mandos.

1 <ul class="heroes">
2   <li *ngFor="let hero of heroes">
3     <a routerLink="/detail/{{hero.id}}">
4       <span class="badge">{{hero.id}}</span> {{hero.name}}
5     </a>
6   </li>
7 </ul>

Tendrás que arreglar la hoja de estilos privada heroes.component.css) para hacer que el listado tenga el
mismo aspecto que antes. Los estilos revisados están en la revisión nal de código al nal de esta página.

Eliminar el código no usado (opcional)

Aunque la clase HeroesComponent aún funciona, el método onSelect() y la propiedad selectedHero ya


no se usan.
Es buena idea ser ordenado y te lo agradecerás en un futuro. Así queda la clase tras quitar el código que ya no
se usa.

1 export class HeroesComponent implements OnInit {


2   heroes: Hero[];
3  
4   constructor(private heroService: HeroService) { }
5  
6   ngOnInit() {
7     this.getHeroes();
8   }
9  
10   getHeroes(): void {
11     this.heroService.getHeroes()
12     .subscribe(heroes => this.heroes = heroes);
13   }
14 }

HeroDetailComponent enrutable

Anteriormente, el padre HeroesComponent estableció la propiedad HeroDetailComponent.hero y He‐


roDetailComponent mostró la propiedad.
GeroesComponent ya no hace eso. Ahora el enrutador crea HeroDetailComponent en respuesta a una
URL del tipo ~/detail/11 .
HeroDetailComponent necesita una nueva manera de obtener el héroe a mostrar.

Obtener la ruta que lo creó.


Extraer el id de la ruta.

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 10/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish

Obtener el héroe con ese id del servidor a través de HeroService .

Añade las siguientes importaciones:

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


2 import { Location } from '@angular/common';
3  
4 import { HeroService }  from '../hero.service';

Inyecta ActivatedRoute , HeroService y Location en el constructor, guardando sus valores en cam-


pos privados:

1 constructor(
2   private route: ActivatedRoute,
3   private heroService: HeroService,
4   private location: Location
5 ) {}

ActivatedRoute guarda información acerca de la ruta a esta instancia de HeroDetailComponent . Este


componente toma en cuenta los parámetros de la ruta extraídos de la URL. El parámetro «id» es el id del hé-
roe a mostrar.
HeroService obtiene datos del héroe desde un servidor remoto y este componente los usará para obtener
el héroe a mostrar.
location es un servicio de Angular para interactuar con el navegador. Lo usaremos más adelante para na-
vegar de vuelta a la vista que nos llevó hasta aquí.

Extraer el id del parámetro de la ruta

En el ‘enganche de ciclo de vida’ (lifecycle hook) ngOnInit() llama a getHero() y defínelo así:

1 ngOnInit(): void {
2   this.getHero();
3 }
4  
5 getHero(): void {
6   const id = +this.route.snapshot.paramMap.get('id');
7   this.heroService.getHero(id)
8     .subscribe(hero => this.hero = hero);
9 }

route.snapshot es una imagen estática de la información de la ruta justo después de que el componente
se haya creado.
paramMap es un diccionario de valores de los parámetros de la ruta, extraídos de la URL. La clave id de-
vuelve el id del héroe a recuperar.
Los parámetros de la ruta son siempre cadenas (strings). El operador de JavaScript (+) convierte la cadena a un
número, que es lo que el id del héroe debería ser.

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 11/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish

El navegador se actualiza y la aplicación fallará con un error del compilador. HeroService no tiene el méto-
do getHero() .Ahora lo añadiremos.

1 getHero(id: number): Observable<Hero> {


2   // Todo: send the message _after_ fetching the hero
3   this.messageService.add(`HeroService: fetched hero id=${id}`);
4   return of(HEROES.find(hero => hero.id === id));
5 }

La comilla invertida (`) en JavaScript de ne un literal de plantilla para embeber el id .

Al igual que getHeroes(), getHero() tiene rma asíncrona. Devuelve un héroe simulado como un Obser‐
vable , usando la función de RxJS of() .
Será posible reimplmentar getHero() como una petición Http real sin tener que cambiar el componente
HeroDetailComponent que lo invoca.

Pruébalo

El navegador se actualiza y la aplicación funciona de nuevo. Puedes hacer clic sobre un héroe en el Cuadro de
Mandos o en la lista de héroes y navegar a la vista de detalle de ese héroe.
Si pegas localhost:4200/detail/11 en la barra de direcciones, el enrutador navega hasta la vista de de-
talle del héroe con id:11 , «Mr. Nice».

Encontrar el camino de vuelta

Haciendo clic en el botón ‘volver’ del navegador, puedes volver a la lista de héroes o el Cuadro de Mandos, de-
pendiendo de que vista nos redirigió a la vista detalle.
Sería conveniente tener un botón en la vista HeroDetail que nos permitiera hacer esto.
Añade un botón volver al nal de la plantilla del componente y vincúlalo al método goBack() del
componente.

1 <button (click)="goBack()">go back</button>

Añade un método goBack() a la clase del componente que navegue un paso hacia atrás en el historial del
navegador usando el servicio Location que hemos inyectado previamente.

1 goBack(): void {
2   this.location.back();
3 }

Actualiza el navegador y haz clics. Los usuarios puedes navegar por toda la aplicación, desde el Cuadro de
Mandos a los detalles del héroe y volver, del listado de héroes al mini detalle, a los detalles del héroe y volver

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 12/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish

al listado de nuevo.
Hemos cumplido todos los requisitos de navegación que se propuesieron en esta página.

Revisión final de código

Aquí está el código de los cheros tratados en esta página y tu aplicación debería parecerse a este ejemplo /
descarga ejemplo

AppRoutingModule, AppModule, y HeroService

1 import { NgModule }             from '@angular/core';


2 import { RouterModule, Routes } from '@angular/router';
3  
4 import { DashboardComponent }   from './dashboard/dashboard.component';
5 import { HeroesComponent }      from './heroes/heroes.component';
6 import { HeroDetailComponent }  from './hero-detail/hero-detail.component';
7  
8 const routes: Routes = [
9   { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
10   { path: 'dashboard', component: DashboardComponent },
11   { path: 'detail/:id', component: HeroDetailComponent },
12   { path: 'heroes', component: HeroesComponent }
13 ];
14  
15 @NgModule({
16   imports: [ RouterModule.forRoot(routes) ],
17   exports: [ RouterModule ]
18 })
19 export class AppRoutingModule {}

1 import { NgModule }       from '@angular/core';


2 import { BrowserModule }  from '@angular/platform-browser';
3 import { FormsModule }    from '@angular/forms';
4  
5 import { AppComponent }         from './app.component';
6 import { DashboardComponent }   from './dashboard/dashboard.component';
7 import { HeroDetailComponent }  from './hero-detail/hero-detail.component';
8 import { HeroesComponent }      from './heroes/heroes.component';
9 import { HeroService }          from './hero.service';
10 import { MessageService }       from './message.service';
11 import { MessagesComponent }    from './messages/messages.component';
12  
13 import { AppRoutingModule }     from './app-routing.module';
14  
15 @NgModule({
16   imports: [
17     BrowserModule,
18     FormsModule,
19     AppRoutingModule
20   ],
21   declarations: [
22     AppComponent,
23     DashboardComponent,
24     HeroesComponent,
25     HeroDetailComponent,
26     MessagesComponent
27   ],
28   providers: [ HeroService, MessageService ],
developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 13/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish
29   bootstrap: [ AppComponent ]
30 })
31 export class AppModule { }

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


2  
3 import { Observable } from 'rxjs/Observable';
4 import { of } from 'rxjs/observable/of';
5  
6 import { Hero } from './hero';
7 import { HEROES } from './mock-heroes';
8 import { MessageService } from './message.service';
9  
10 @Injectable()
11 export class HeroService {
12  
13   constructor(private messageService: MessageService) { }
14  
15   getHeroes(): Observable<Hero[]> {
16     // Todo: send the message _after_ fetching the heroes
17     this.messageService.add('HeroService: fetched heroes');
18     return of(HEROES);
19   }
20  
21   getHero(id: number): Observable<Hero> {
22     // Todo: send the message _after_ fetching the hero
23     this.messageService.add(`HeroService: fetched hero id=${id}`);
24     return of(HEROES.find(hero => hero.id === id));
25   }
26 }

AppComponent

1 <h1>{{title}}</h1>
2 <nav>
3   <a routerLink="/dashboard">Dashboard</a>
4   <a routerLink="/heroes">Heroes</a>
5 </nav>
6 <router-outlet></router-outlet>
7 <app-messages></app-messages>

1 /* AppComponent's private CSS styles */


2 h1 {
3   font-size: 1.2em;
4   color: #999;
5   margin-bottom: 0;
6 }
7 h2 {
8   font-size: 2em;
9   margin-top: 0;
10   padding-top: 0;
11 }
12 nav a {
13   padding: 5px 10px;
14   text-decoration: none;
15   margin-top: 10px;
16   display: inline-block;
17   background-color: #eee;
18   border-radius: 4px;
19 }
20 nav a:visited, a:link {

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 14/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish
21   color: #607D8B;
22 }
23 nav a:hover {
24   color: #039be5;
25   background-color: #CFD8DC;
26 }
27 nav a.active {
28   color: #039be5;
29 }

DashboardComponent

1 <h3>Top Heroes</h3>
2 <div class="grid grid-pad">
3   <a *ngFor="let hero of heroes" class="col-1-4"
4       routerLink="/detail/{{hero.id}}">
5     <div class="module hero">
6       <h4>{{hero.name}}</h4>
7     </div>
8   </a>
9 </div>

1 import { Component, OnInit } from '@angular/core';


2 import { Hero } from '../hero';
3 import { HeroService } from '../hero.service';
4  
5 @Component({
6   selector: 'app-dashboard',
7   templateUrl: './dashboard.component.html',
8   styleUrls: [ './dashboard.component.css' ]
9 })
10 export class DashboardComponent implements OnInit {
11   heroes: Hero[] = [];
12  
13   constructor(private heroService: HeroService) { }
14  
15   ngOnInit() {
16     this.getHeroes();
17   }
18  
19   getHeroes(): void {
20     this.heroService.getHeroes()
21       .subscribe(heroes => this.heroes = heroes.slice(1, 5));
22   }
23 }

1 /* DashboardComponent's private CSS styles */


2 [class*='col-'] {
3   float: left;
4   padding-right: 20px;
5   padding-bottom: 20px;
6 }
7 [class*='col-']:last-of-type {
8   padding-right: 0;
9 }
10 a {
11   text-decoration: none;
12 }
13 *, *:after, *:before {
14   -webkit-box-sizing: border-box;
15   -moz-box-sizing: border-box;

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 15/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish
16   box-sizing: border-box;
17 }
18 h3 {
19   text-align: center; margin-bottom: 0;
20 }
21 h4 {
22   position: relative;
23 }
24 .grid {
25   margin: 0;
26 }
27 .col-1-4 {
28   width: 25%;
29 }
30 .module {
31   padding: 20px;
32   text-align: center;
33   color: #eee;
34   max-height: 120px;
35   min-width: 120px;
36   background-color: #607D8B;
37   border-radius: 2px;
38 }
39 .module:hover {
40   background-color: #EEE;
41   cursor: pointer;
42   color: #607d8b;
43 }
44 .grid-pad {
45   padding: 10px 0;
46 }
47 .grid-pad > [class*='col-']:last-of-type {
48   padding-right: 20px;
49 }
50 @media (max-width: 600px) {
51   .module {
52     font-size: 10px;
53     max-height: 75px; }
54 }
55 @media (max-width: 1024px) {
56   .grid {
57     margin: 0;
58   }
59   .module {
60     min-width: 60px;
61   }
62 }

HeroesComponent

1 <h2>My Heroes</h2>
2 <ul class="heroes">
3   <li *ngFor="let hero of heroes">
4     <a routerLink="/detail/{{hero.id}}">
5       <span class="badge">{{hero.id}}</span> {{hero.name}}
6     </a>
7   </li>
8 </ul>

1 import { Component, OnInit } from '@angular/core';


2  
3 import { Hero } from '../hero';
developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 16/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish
4 import { HeroService } from '../hero.service';
5  
6 @Component({
7   selector: 'app-heroes',
8   templateUrl: './heroes.component.html',
9   styleUrls: ['./heroes.component.css']
10 })
11 export class HeroesComponent implements OnInit {
12   heroes: Hero[];
13  
14   constructor(private heroService: HeroService) { }
15  
16   ngOnInit() {
17     this.getHeroes();
18   }
19  
20   getHeroes(): void {
21     this.heroService.getHeroes()
22     .subscribe(heroes => this.heroes = heroes);
23   }
24 }

1 /* HeroesComponent's private CSS styles */


2 .heroes {
3   margin: 0 0 2em 0;
4   list-style-type: none;
5   padding: 0;
6   width: 15em;
7 }
8 .heroes li {
9   position: relative;
10   cursor: pointer;
11   background-color: #EEE;
12   margin: .5em;
13   padding: .3em 0;
14   height: 1.6em;
15   border-radius: 4px;
16 }
17  
18 .heroes li:hover {
19   color: #607D8B;
20   background-color: #DDD;
21   left: .1em;
22 }
23  
24 .heroes a {
25   color: #888;
26   text-decoration: none;
27   position: relative;
28   display: block;
29   width: 250px;
30 }
31  
32 .heroes a:hover {
33   color:#607D8B;
34 }
35  
36 .heroes .badge {
37   display: inline-block;
38   font-size: small;
39   color: white;
40   padding: 0.8em 0.7em 0 0.7em;
41   background-color: #607D8B;
42   line-height: 1em;

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 17/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish
43   position: relative;
44   left: -1px;
45   top: -4px;
46   height: 1.8em;
47   min-width: 16px;
48   text-align: right;
49   margin-right: .8em;
50   border-radius: 4px 0 0 4px;
51 }

HeroDetailComponent

1 <div *ngIf="hero">
2   <h2>{{ hero.name | uppercase }} Details</h2>
3   <div><span>id: </span>{{hero.id}}</div>
4   <div>
5     <label>name:
6       <input [(ngModel)]="hero.name" placeholder="name"/>
7     </label>
8   </div>
9   <button (click)="goBack()">go back</button>
10 </div>

1 import { Component, OnInit, Input } from '@angular/core';


2 import { ActivatedRoute } from '@angular/router';
3 import { Location } from '@angular/common';
4  
5 import { Hero }         from '../hero';
6 import { HeroService }  from '../hero.service';
7  
8 @Component({
9   selector: 'app-hero-detail',
10   templateUrl: './hero-detail.component.html',
11   styleUrls: [ './hero-detail.component.css' ]
12 })
13 export class HeroDetailComponent implements OnInit {
14   @Input() hero: Hero;
15  
16   constructor(
17     private route: ActivatedRoute,
18     private heroService: HeroService,
19     private location: Location
20   ) {}
21  
22   ngOnInit(): void {
23     this.getHero();
24   }
25  
26   getHero(): void {
27     const id = +this.route.snapshot.paramMap.get('id');
28     this.heroService.getHero(id)
29       .subscribe(hero => this.hero = hero);
30   }
31  
32   goBack(): void {
33     this.location.back();
34   }
35 }

1 /* HeroDetailComponent's private CSS styles */


2 label {

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 18/19
20/7/2019 Tutorial Angular – 7. Enrutamiento. – Developing in Spanish
3   display: inline-block;
4   width: 3em;
5   margin: .5em 0;
6   color: #607D8B;
7   font-weight: bold;
8 }
9 input {
10   height: 2em;
11   font-size: 1em;
12   padding-left: .4em;
13 }
14 button {
15   margin-top: 20px;
16   font-family: Arial;
17   background-color: #eee;
18   border: none;
19   padding: 5px 10px;
20   border-radius: 4px;
21   cursor: pointer; cursor: hand;
22 }
23 button:hover {
24   background-color: #cfd8dc;
25 }
26 button:disabled {
27   background-color: #eee;
28   color: #ccc;
29   cursor: auto;
30 }

Resumen

Hemos añadido un enrutador de Angular para navegar entre diferentes componentes.


Hemos convertido a AppComponent en un caparazón (shell) de navegación con enlaces <a> y un
<router-outlet> .
Hemos con gurado el enrutador en AppRoutingModule .
Hemos de nido rutas sencillas, una ruta de redirección y una ruta parametrizada.
Hemos usado la directiva RouterLink en elementos <a> .
Hemos refactorizado una vista maestro/detalle fuertemente acoplada en una vista de detalle enrutada.
Hemos usado los parámetros del enlace de la ruta para navegar a la vista del detalle de un héroe selec-
cionado por el usuario.
Hemos compartido el servicio HeroServices entre múltiples componentes.

Nota: puedes encontrar el documento original de esta entrada en https://angular.io/tutorial/toh-pt5

 Angular, Tutorial

developinginspanish.com/2018/03/13/tutorial-angular-7-enrutamiento/ 19/19

S-ar putea să vă placă și