construye minioland

Construye Minioland: Tu primera aplicaci贸n con Angular | Parte #2

脷ltima actualizaci贸n:

NOTA

Esta es la parte #2 de la serie sobre la creaci贸n de Minioland, una aplicaci贸n sencilla con Angular. Si te perdiste la parte #1, aqu铆 la tienes.

Trabajando con las routes de Angular

Las routes son las herramientas que nos van a permitir navegar de una p谩gina a otra de nuestra app sin que nuestro navegador se recargue. 

Por ejemplo, ahora nuestro navegador muestra http://localhost:4200/, pero implementando rutas vamos a conseguir crear direcciones tales como http://localhost:4200/home, http://localhost:4200/about, etc.

1. Creamos un archivo dentro de nuestra carpeta app, llamado app.routes.tsEl .routes no es obligatorio, pero es una convenci贸n para que identifiquemos a golpe de vista que es un archivo de rutas. Otra cosa que me ayuda a identificarlo r谩pidamente es su caracter铆stico icono (una se帽al de tr谩fico mostrando distintas direcciones). Lo puedes conseguir a trav茅s de extensiones de vsCode, (Material icon theme). 

El contenido de nuestro archivo app.routes.ts lo podemos generar con la ayuda de un Angular snippet gracias a una extensi贸n de vsCode (busca Angular snippets en la secci贸n de extensiones).

El resultado ser铆a algo as铆: 

import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './components/home/home.component'; const routes: Routes = [ { path: 'home', component: HomeComponent}, { path: '**', pathMatch: 'full', redirectTo: 'home' }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule {}

Como podemos ver, la variable routes es un array de rutas. Cada ruta contiene un path a uno de nuestros componentes y el nombre de dicho componente. 

Debemos dejar siempre al final la ruta path: '**', pues es una ruta especial que se activar谩 si existe alg煤n error en nuestras rutas y Angular no puede localizarlas, redireccion谩ndonos a la ruta que le marquemos en redirectTo. 

En nuestro caso, vamos a redireccionar a nuestra home.鈥嬧嬧嬧

Es necesario que importemos todos los componentes cuyas rutas vamos a necesitar. 

Por tanto, a帽adimos nuestras rutas para los componentes de about minions, tal y como hemos hecho con el home component.

2. Avisamos a Angular de que hemos creado un archivo de rutas.

Para ello, vamos al archivo app.module.ts (por cierto, para no ir buscando uno a uno entre nuestra lista casi infinita de archivos de la izquierda, suelo a hacer ctrl+p para buscar un archivo en vsCode), e importamos nuestro archivo de rutas ah铆. 

Ahora nuestro archivo app.module.ts tiene este aspecto:

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; // routes import { AppRoutingModule } from './app.routes'; // components import { AppComponent } from './app.component'; import { NavbarComponent } from './components/shared/navbar/navbar.component'; import { HomeComponent } from './components/home/home.component'; import { AboutComponent } from './components/about/about.component'; import { MinionsComponent } from './components/minions/minions.component'; @NgModule({ declarations: [ AppComponent, NavbarComponent, HomeComponent, AboutComponent, MinionsComponent ], imports: [ BrowserModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }

3. Para que nuestras rutas funcionen tenemos que hacer un 煤ltimo paso, ya que Angular todav铆a no sabe qu茅 ruta debe mostrar cuando nuestra app se cargue por primera vez. 

Para ello, vamos al archivo que Angular utiliza para cargar nuestra app (el app.component.html) e incluimos esta etiqueta:

<router-outlet></router-outlet>

La podemos incluir dentro de un container de bootstrap, quedando nuestro c贸digo del app.component.html as铆:

<app-navbar></app-navbar> <div class="container-fluid"> <router-outlet></router-outlet> </div>

A帽adiendo routerLink y routerLinkActive

Seguimos configurando nuestras rutas. 

Desde nuestro navbar vamos a gestionar hacia d贸nde apuntar谩n nuestros links. Por ahora solo tenemos el link home y uno que viene por defecto con bootstrap.

1. Eliminamos la clase active del link home y a帽adimos nuestros links de about minions.

Borramos tambi茅n el atributo href de nuestros links porque lo vamos a sustituir por una propiedad de Angular, el routerLink. Esta propiedad admite un array de los diferentes niveles de una ruta, donde cada nivel es un elemento del array. Por ejemplo, si queremos una ruta que nos lleve a una p谩gina (ficticia) de Sobre Nosotros y ah铆 dentro existiese un link a otra p谩gina llamada Aparaciones en los medios, la sintaxis ser铆a:

[routerLink]="['/sobre-nosotros', '/medios']"

que en el navegador se traducir铆a en http://localhost:4200/sobre-nosotros/medios

馃 隆Ojo! El nombre que le demos en el routerLink debe coincidir con el que el que le hemos dado a la ruta en nuestro archivo app.routes.ts.

隆Y ya est谩! Ahora deber铆as poder navegar entre las diferentes p谩ginas de tu app, viendo as铆 su contenido.

2. Reforzamos la visibilidad del link de la p谩gina en la que nos encontramos en este momento.

Para ello, al parent element del elemento que tenga la propiedad  [routerLink]="['/nombre de la ruta']", le a帽adimos routerLinkActive="active"Active es una clase CSS de bootstrap, pero podr铆amos a帽adir nuestra propia clase. 

馃 Cuidado con esto de poner tu clase personalizada, porque existe un conflicto de specificity con las clases de bootstrap. Para solucionarlo, coloca el [routerLink] y el routerLinkActive en el mismo elemento HTML, y define tu clase CSS en el archivo styles.css de la siguiente manera:

.myActiveClass.myActiveClass.myActiveClass.myActiveClass {

 // tu c贸digo aqu铆

}

En este caso no voy a utilizar un clase CSS personalizada, sino la clase active que nos ofrece bootstrap, quedando as铆 nuestro c贸digo del archivo navbar.component.html:

<nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <a class="navbar-brand" href="#">Minioland</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> <li class="nav-item" routerLinkActive="active"> <a class="nav-link" [routerLink]="['/home']" >Home<span class="sr-only">(current)</span></a> </li> <li class="nav-item" routerLinkActive="active"> <a class="nav-link" [routerLink]="['/minions']" >Minions</a> </li> <li class="nav-item" routerLinkActive="active"> <a class="nav-link" [routerLink]="['/about']" >About</a> </li> </ul> <form class="form-inline my-2 my-lg-0"> <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search"> <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> </form> </div> </nav>

Peque帽as animaciones con CSS

En los materiales del proyecto encontrar谩s un archivo llamado animate. Copia su contenido y vu茅lcalo en el archivo styles.css, que est谩 al nivel de la carpeta app. 

El archivo es un extracto de animate.css, web muy 煤til. 

A帽adimos las siguientes clases a nuestros componentes about home, en los divs que engloben el componente. Por ejemplo, el home component quedar铆a as铆:

<div class="jumbotron jumbotron-fluid animated fadeIn fast"> <div class="container"> <h1 class="display-4">Minioland</h1> <p class="lead">Pon un Minion en tu vida.</p> </div> </div>

Dise帽ando el componente minions

La estructura de nuestro minions component  se va a basar en los componentes cards que nos ofrece bootstrap 4.

1. Por ahora, vamos a escribir el src del elemento img en modo hardcoded, al igual que el t铆tulo y el subt铆tulo de la card. Nos ocuparemos de hacerlo din谩mico luego, utilizando una herramienta de Angular llamada service. Un service es un archivo donde guardamos datos que queremos reutilizar, con el objetivo de no repetir c贸digo

Por ejemplo, en este caso, podr铆amos a帽adir dentro del componente minions.component.html el contenido del nombre del minion y su bio, pero esto no ser铆a eficiente, porque en caso de necesitar esa informaci贸n en otro componente deber铆amos repetir el mismo c贸digo en el otro componente. Eso es lo que los services resuelven.

2. Tambi茅n vamos a darle un peque帽o estilo a nuestra imagen. Para ello debemos modificar el archivo minions.component.css, quedando de la siguiente manera:

img { width: 50%; position: relative; left: 25%; }

Nuestro archivo minions.component.html nos quedar铆a as铆:

<h2 class="mt-4">Minions <small>a mansalva</small></h2>
<hr>

<div class="container">
<div class="card-columns mb-5">
<div class="card">
<img src="../../../assets/img/tu-imagen-aqui.jpg" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">This card has supporting text below as a natural lead-in to additional content.</p>
<p class="card-text"><small class="text-muted"> Last updated 3 days ago </small></p>
<button type="button" class="btn btn-outline-warning btn-block">Ver m谩s info</button>
</div>
</div>
</div>
</div>

Como ves, hemos a帽adido un bot贸n, el cual, una vez configurado, nos deber谩 llevar a una p谩gina donde podremos ver m谩s informaci贸n sobre el minion que hayamos hecho clic.

Introducci贸n y creaci贸n de services en Angular

Como ya adelantamos en el anterior punto, vamos a utilizar un service para almacenar la informaci贸n (aka data) de nuestros minions.

1. Creamos nuestra carpeta para almacenar nuestros servicios dentro de la carpeta app y la nombramos como queramos, aunque es una convenci贸n llamarla services.

Dentro de esta carpeta, creamos un archivo al que llamaremos minions.service.ts. El .service es una convenci贸n para poder identificarlo a golpe de vista. 

Puedes utilizar un snippet de la extensi贸n de angular para generar el esqueleto de un service.鈥嬧嬧

Lo que identifica un service como tal es su decorador @Injectable().鈥嬧嬧嬧

Nuestro c贸digo del archivo minions.service.ts quedar铆a as铆:

import { Injectable } from '@angular/core'; @Injectable() export class MinionsService { constructor() { console.log('minions service listo para usar, oiga!'); } }

Hemos a帽adido un console.log para comprobar que el service funciona.

2. Tenemos que avisar a Angular de que hemos creado un servicio nuevo. 

Para ello, vamos a nuestro app.module.ts y lo declaramos ah铆, tanto en los imports como en los providers鈥嬧嬧嬧, quedando nuestro archivo as铆:

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; // routes import { AppRoutingModule } from './app.routes'; // services import { MinionsService } from './services/minions.service'; // components import { AppComponent } from './app.component'; import { NavbarComponent } from './components/shared/navbar/navbar.component'; import { HomeComponent } from './components/home/home.component'; import { AboutComponent } from './components/about/about.component'; import { MinionsComponent } from './components/minions/minions.component'; @NgModule({ declarations: [ AppComponent, NavbarComponent, HomeComponent, AboutComponent, MinionsComponent ], imports: [ BrowserModule, AppRoutingModule ], providers: [MinionsService], bootstrap: [AppComponent] }) export class AppModule { }

3. Importamos el service en el componente donde queramos utilizarlo. En nuestro caso, en el minions.component.ts, quedando nuestro c贸digo de la siguiente manera: 

import { Component, OnInit } from '@angular/core'; import { MinionsService } from 'src/app/services/minions.service'; @Component({ selector: 'app-minions', templateUrl: './minions.component.html', styleUrls: ['./minions.component.css'] }) export class MinionsComponent implements OnInit { constructor(private minionsService: MinionsService) { } ngOnInit() { } }

Esta es la primera vez que vamos a usar el constructor.

4. A帽adimos la palabra reservada private, ya que queremos declarar una propiedad accesible solamente en este componente.

Le damos un alias a nuestra propiedad y la declaramos como tipo MinionsService.鈥嬧嬧嬧

Al guardar, vamos a nuestra app y deber铆amos ver en las dev tools de chrome nuestro console.log('minions service listo para usar, oiga!').

Ten en cuenta que ese console.log solo se ve en la p谩gina de Minions. No en el Home ni en el About, ya que s贸lo estamos usando el service en la p谩gina de Minions.

Esto es lo que deber铆as ver:

minions service listo

5. Rellenamos con datos nuestro MinionsService.

Para ello, vamos a nuestro service (minions.service.ts) donde declaramos una propiedad privada de tipo any[], llamada minions.

Vamos a los materiales del proyecto y abrimos el archivo .txtdonde encontramos un array de objetos. Copiamos toda la informaci贸n y la pegamos dentro de nuestra propiedad minions reci茅n creada.

6. Ya que hemos declarado nuestra data como una propiedad privada, necesitamos crear un m茅todo p煤blico para poder acceder a esa propiedad desde fuera de nuestro servicio. Este paso no es estrictamente necesario para esta simple app, pero es una buena pr谩ctica por si en el futuro queremos trabajar con APIs. 馃槑

El m茅todo lo vamos llamar getMinions(). 

A帽adimos tambi茅n una interface de Angular para fortalecer nuestro c贸digo y as铆 evitar errores. B谩sicamente, con la interface lo que hacemos es declarar que cada minion va a tener un name, bio, img, birth side, de manera que si de ahora en adelante nos equivocamos en alguna de esas caracter铆sticas, Angular nos lanzar谩 un error diciendo que cada minion puede tener esas 煤nicas caracter铆sticas, ni m谩s ni menos.

El c贸digo de nuestro MinionsService quedar铆a de la siguiente manera:

import { Injectable } from '@angular/core'; @Injectable() export class MinionsService { private minions: Minion[] = [ { name: "Kevin", bio: "Aqu铆 deber铆a haber una biograf铆a de la vida de este minion, pero son gente muy misteriosa, as铆 que tendr谩s que imagin谩rtela...", img: "assets/img/kevin.jpg", birth: "1951", side:"de los buenos" }, { name: "Josua", bio: "Aqu铆 deber铆a haber una biograf铆a de la vida de este minion, pero son gente muy misteriosa, as铆 que tendr谩s que imagin谩rtela...", img: "assets/img/Josua.jpg", birth: "1672", side:"malvado" }, { name: "Dave", bio: "Aqu铆 deber铆a haber una biograf铆a de la vida de este minion, pero son gente muy misteriosa, as铆 que tendr谩s que imagin谩rtela...", img: "assets/img/dave.png", birth: "1723", side: "de los buenos" }, { name: "Mudito", bio: "Aqu铆 deber铆a haber una biograf铆a de la vida de este minion, pero son gente muy misteriosa, as铆 que tendr谩s que imagin谩rtela...", img: "assets/img/mudito.jpeg", birth: "1379", side:"de los buenos" }, { name: "Llongueras", bio: "Aqu铆 deber铆a haber una biograf铆a de la vida de este minion, pero son gente muy misteriosa, as铆 que tendr谩s que imagin谩rtela...", img: "assets/img/llongueras.jpg", birth: "1687", side: "malvado" }, { name: "Minionc茅", bio: "Le va el cante, dar la nota, ama los karaokes, es el rey y reina de la fiesta. Inv铆talo a tu fiesta o te arrepentir谩s.", img: "assets/img/minionce.jpg", birth: "1976", side: "de los buenos" }, { name: "Lobeznion", bio: "No lo enfades, este bichillo tiene muy malas pulgas...aunque s贸lo mide medio metro y 隆no puede ser m谩s gracioso!", img: "assets/img/lobeznion.jpg", birth: "2017", side: "malvado" }, { name: "Minion Presley", bio: "Aqu铆 deber铆a haber una biograf铆a de la vida de este minion, pero son gente muy misteriosa, as铆 que tendr谩s que imagin谩rtela...", img: "assets/img/minion-presley.jpg", birth: "2017", side: "malvado" } ]; constructor() { console.log('minions service listo para usar, oiga!'); } getMinions() { return this.minions; } } export interface Minion { name: string; bio: string; img: string; birth: string; side: string; }

7. Y ahora, 驴c贸mo trasladamos los datos que hemos puesto en nuestro MinionsService para que se vean reflejados en nuestro MinionsComponent? Declarando una propiedad, a la que llamaremos tambi茅n minions, que ser谩 de tipo Minion (esto sale de nuestra interface) en nuestro minions.component.ts y asign谩ndole el valor de la propiedad minions de nuestro archivo minions.service.ts y el m茅todo para obtener la informaci贸n de los minions (getMinions() )

Esto lo vamos a hacer dentro del bloque del ngOnInit() { }.

Y as铆 de sencillo es conectar un servicio con un componente.

Haz un console.log de minions en el ngOnInit() y ver谩s que la lista de minions aparece en tus dev tools.

Aqu铆 el c贸digo de minions.component.ts tal y como quedar铆a:

import { Component, OnInit } from '@angular/core'; import { MinionsService, Minion } from 'src/app/services/minions.service'; @Component({ selector: 'app-minions', templateUrl: './minions.component.html', styleUrls: ['./minions.component.css'] }) export class MinionsComponent implements OnInit { minions: Minion[] = []; constructor(private minionsService: MinionsService) { } ngOnInit() { this.minions = this.minionsService.getMinions(); console.log(this.minions); } }

Aplicando el *ngFor para generar minions

Vamos a usar una herramienta verdaderamente 煤til que nos proporciona Angular: el *ngForEl *ngFor es una directive de Angular que nos permite realizar loops de manera muy sencilla.

La vamos a usar para generar minions din谩micamente a partir del esqueleto o plantilla base que tenemos definida en nuestra card de bootstrap del minions.component.html: su foto, su nombre, un resumen de su biograf铆a y un bot贸n para ver su informaci贸n completa.

En nuestro minions.component.ts tenemos nuestra variable local minions. Esa variable la vamos a usar de referencia en el archivo minions.component.html. 

1. La forma de usar este loop es creando una variable local, a la que, siendo l贸gicos, llamaremos minion y le pasaremos nuestra variable minions del archivo minions.component.ts.

Comprueba por ti mismo la conexi贸n que acabamos de crear poniendo el rat贸n encima de minions y clicando ctrl+clic izq. Ver谩s que te lleva a tu archivo de typescript (minions.component.ts)馃憦 Tach谩谩谩n!! 馃帀

2. Convertimos las propiedades de nuestros minions en din谩micas, y no hardcoded, como estaban hasta ahora.

Para ello vamos a usar una t茅cnica de Angular llamada property binding, la cual nos permite convertir atributos de un elemento HTML, como el src, en atributos que interact煤an con Angular inform谩ndole de lo que nosotros le digamos.

En este caso, vinculamos el atributo src del elemento img y utilizamos nuestra variable local minion del *ngFor junto con nuestra propiedad img, creada para cada minion en nuestra interface.

Hacemos lo mismo con el atributo alt de la imagen.

Con el nombre y la bio del minion no podemos hacer property binding, as铆 que utilizamos otra t茅cnica para informar a Angular llamada string interpolation.  

Nuestro c贸digo del minions.component.html quedar铆a as铆:

<h2 class="mt-4">Minions <small>a mansalva</small></h2>
<hr>

<div class="container">
<div class="card-columns mb-5">
<div class="card" *ngFor="let minion of minions">
<img [src]="minion.img" class="card-img-top" [alt]="minion.name">
<div class="card-body">
<h5 class="card-title"> {{ minion.name }} </h5>
<p class="card-text"> {{ minion.bio }} </p>
<p class="card-text"><small class="text-muted"> {{ minion.birth }} </small></p>
<button type="button" class="btn btn-outline-warning btn-block">Ver m谩s info</button>
</div>
</div>
</div>
</div>

Y ahora nuestra p谩gina de Minions se ve as铆:

minions page

Configurando la navegaci贸n entre nuestras p谩ginas

Ya tenemos el componente MinionsComponent, que nos muestra una visi贸n general de todos nuestros minions. Ahora es momento de crear otro componente que ser谩 la p谩gina donde seremos dirigidos cuando hagamos click en el bot贸n de Ver m谩s info de alguna de las cards  de nuestro componente MinionsComponent. 

1. Creamos el componente (al que llamaremos minion) en app --> components, usando Angular CLI.

ng g c minion --skipTests

2. Actualizamos nuestro archivo de rutas (app.routes.ts), informando as铆 a Angular de que hemos creado una nueva route para poder navegar hasta y desde ella. As铆 nos queda:

import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './components/home/home.component'; import { AboutComponent } from './components/about/about.component'; import { MinionsComponent } from './components/minions/minions.component'; import { MinionComponent } from './components/minion/minion.component'; const routes: Routes = [ { path: 'home', component: HomeComponent}, { path: 'about', component: AboutComponent}, { path: 'minions', component: MinionsComponent}, { path: 'minion/:id', component: MinionComponent}, { path: '**', pathMatch: 'full', redirectTo: 'home' }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule {}

Aqu铆 viene lo nuevo. Cuando le pasemos un path a la ruta, no podemos simplemente llamarlo minion, sino que necesitaremos pasarle un par谩metro. Sencillamente porque cuando hagamos clic en el bot贸n de Ver m谩s info de nuestro minion Dave, por ejemplo, Angular nos llevar谩 al componente que acabamos de crear (MinionComponent) pero debemos informarle cu谩l de todos nuestros minions queremos ver, que deber谩 coincidir, claro, con el minion que hayamos hecho clic. En este caso, deber谩 mostrarnos la "p谩gina de Dave", por as铆 decirlo. 

Es el mismo concepto que cuando est谩s navegando por Netflix y seleccionas una serie. Al seleccionarla, Netflix te lleva a la p谩gina de esa serie.

Pues lo mismo aqu铆, mil veces m谩s sencillo 馃槄

A nuestro par谩metro lo vamos a llamar id porque 茅se es el standard y lo l贸gico: cada uno de nuestros minions es 煤nico y por tanto, tiene sentido que cada uno tenga un id distinto.

驴Pero de d贸nde sacamos ese id, si no le hemos dado ninguno a nuestros minions? 馃

Pues del array de minions que tenemos en nuestras dev tools de chrome, que sale de nuestro console.log del minions.component.ts:

array minions dev tools

As铆 que con esta informaci贸n del console.log podemos saber qu茅 铆ndice (o id) tiene cada uno de nuestros minions. Por ejemplo, Kevin tiene el 铆ndice 0. 

3. A este 铆ndice podemos acceder f谩cilmente desde nuestro c贸digo en minions.component.html usando la propiedad index y a帽adi茅ndola como parte del *ngFor:

<div class="card" *ngFor="let minion of minions; let i = index;">

4. Nos creamos el m茅todo seeMinion() en el archivo de typescript de ese mismo componente (en seguida lo explicaremos) :

seeMinion(idx: number) {

 this.router.navigate(['/minion', idx]);

}

Nuestro c贸digo del minions.component.html quedar铆a de la siguiente manera:

<h2 class="mt-4">Minions <small>a mansalva</small></h2>
<hr>

<div class="container">
<div class="card-columns mb-5">
<div class="card" *ngFor="let minion of minions; let i = index;">
<img [src]="minion.img" class="card-img-top" [alt]="minion.name">
<div class="card-body">
<h5 class="card-title"> {{ minion.name }} </h5>
<p class="card-text"> {{ minion.bio }} </p>
<p class="card-text"><small class="text-muted"> {{ minion.birth }} </small></p>
<button type="button" class="btn btn-outline-warning btn-block" (click)="seeMinion(i)">Ver m谩s info</button>
</div>
</div>
</div>
</div>

Para que nuestro m茅todo funcione tenemos que importar el m贸dulo Router de @angular/router en minions.component.ts e inyectarlo en nuestro constructor creando una variable de ese tipo (Router).

Nuestro c贸digo del minions.component.ts nos quedar铆a as铆:

import { Component, OnInit } from '@angular/core'; import { MinionsService, Minion } from 'src/app/services/minions.service'; import { Router } from '@angular/router'; @Component({ selector: 'app-minions', templateUrl: './minions.component.html', styleUrls: ['./minions.component.css'] }) export class MinionsComponent implements OnInit { minions: Minion[] = []; constructor(private minionsService: MinionsService, private router: Router) { } ngOnInit() { this.minions = this.minionsService.getMinions(); console.log(this.minions); } seeMinion(idx: number) { this.router.navigate(['/minion', idx]); } }

隆Y voil脿! Ahora si clicas en cualquier minion desde la p谩gina de minions te llevar谩 a su p谩gina espec铆fica, que de momento deber铆a decir no m谩s que minion works!

Por ejemplo, si clicas en el bot贸n de Ver m谩s info del minion Kevin, ver谩s que tu url ahora es http://localhost:4200/minion/0 , siendo 0 el id que representa a nuestro querido Kevin.

THE END! (POR AHORA...) 

Y hasta aqu铆 la parte #2 de esta serie de posts sobre c贸mo construir una sencilla aplicaci贸n con Angular. Si quieres seguir aprendiendo, aqu铆 tienes la parte #3Y si te perdiste la parte #1, aqu铆 la tienes.

M谩s recursos de aprendizaje

Aprender Angular a trav茅s de tutoriales web y cursos online est谩 genial, pero si necesitas un apoyo en forma de libro, puede que 茅stos te sirvan de ayuda:

La programaci贸n es un mundo que evoluciona a una velocidad de v茅rtigo. Los autores de estos libros lo saben, por eso suelen encargarse de actualizar su contenido regularmente. Aseg煤rate de que as铆 sea antes de adquirirlos 馃槍.

COMPARTIR ES VIVIR

Si crees que este post puede serle 煤til a alguien, 隆comp谩rtelo!

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende c贸mo se procesan los datos de tus comentarios.

Como toda web legal que se precie, utilizamos cookies para asegurar que damos la mejor experiencia al usuario en nuestro sitio web. Si contin煤as utilizando este sitio asumiremos que est谩s de acuerdo. m谩s informaci贸n

Los ajustes de cookies de esta web est谩n configurados para "permitir cookies" y as铆 ofrecerte la mejor experiencia de navegaci贸n posible. Si sigues utilizando esta web sin cambiar tus ajustes de cookies o haces clic en "Aceptar" estar谩s dando tu consentimiento a esto.

Cerrar