Angular
Magni Gerardo
PROGRAMACIÓN ANGULAR
Reutilización de Componentes
Comenzamos modificando nuestro proyecto anterior “sitioangular”, el primer objetivo será crear un
componente para la tarjeta, de tal forma sea reutilizable.
Por lo tanto creamos un nuevo componente
ng g c components/heroeTarjeta --spec=false
Modifico el componente héroes quitando el ngFor y eliminado el código de la tarjeta de esta forma:
<h1>Heroes de Marvel y de DC Comics</h1>
<hr>
<div class="card-columns">
<!--*ngFor="let heroeAux of heroes; let i = index"-->
</div>
El código eliminado lo asigno en el nuevo componente heroeTarjeta
<div class="card animated fadeIn fast">
<img class="card-img-top" src="{{heroeAux.img}}" [alt]="heroeAux">
<div class="card-body">
<h5 class="card-title">{{heroeAux.nombre}}</h5>
<p class="card-text">{{heroeAux.bio}}</p>
<p class="card-text">
<small class="text-muted">{{heroeAux.aparicion}}</small>
</p>
<button (click)="verHeroe(i)" type="button" class="btn btn-outline-primary btn-block">Ver
Mas</button>
</div>
</div>
Modifico héroe-tarjeta.component.ts agregando una variable
heroeAux:Heroe;
import { Component, OnInit, Input } from '@angular/core';
import { Heroe } from '../../servicios/heroes.service';
@Component({
selector: 'app-heroe-tarjeta',
templateUrl: './heroe-tarjeta.component.html',
Ing. Gerardo Magni Página 1
Angular
Magni Gerardo
styleUrls: ['./heroe-tarjeta.component.css']
})
export class HeroeTarjetaComponent implements OnInit {
heroeAux:Heroe;
constructor() { }
ngOnInit() {
}
}
Reutilizo el nuevo componente en héroes.component
<h1>Heroes de Marvel y de DC Comics</h1>
<hr>
<div class="card-columns">
<!--*ngFor="let heroeAux of heroes; let i = index"-->
<app-heroe-tarjeta *ngFor="let heroeAux of heroes; let i = index"></app-heroe-tarjeta>
</div>
Ahora nuestro objetivo es poder pasar un parámetro desde nuestro componente padre a un componente
hijo (app-heroe-tarjeta) para lograr esto usaremos los @Input los cuales indican que una propiedad será
recepcionada desde fuera del componente actual.
@Input
@Input() heroeAux:Heroe;
Modificamos la definición de la variable agregando el @Input, con lo cual le indicamos a angular que el
valor de la variable puede venir desde afuera. Por lo tanto ahora podemos hacer lo siguiente.
<h1>Heroes de Marvel y de DC Comics</h1>
<hr>
<div class="card-columns">
<!--*ngFor="let heroeAux of heroes; let i = index"-->
<app-heroe-tarjeta *ngFor="let heroeLocal of heroes; let i = index" [heroeAux]="heroeLocal"
></app-heroe-tarjeta>
</div>
Siendo [heroeAux] el nombre de la variable declarada en el componente app-heroe-tarjeta
Ing. Gerardo Magni Página 2
Angular
Magni Gerardo
Si presionamos en el Botón “Ver Mas…” de la tarjeta veremos que no funciona y emite error, debemos
hacer algunas modificaciones para subsanar el error:
Crear el Método verHeroe() en el componente tarjeta y agregar un nuevo Input para manejar el id de cada
tarjeta:
import { Component, OnInit, Input } from '@angular/core';
import { Heroe } from '../../servicios/heroes.service';
@Component({
selector: 'app-heroe-tarjeta',
templateUrl: './heroe-tarjeta.component.html',
styleUrls: ['./heroe-tarjeta.component.css']
})
export class HeroeTarjetaComponent implements OnInit {
@Input() heroeAux:Heroe;
@Input() index:number;
constructor() { }
ngOnInit() {
}
public verHeroe(){
console.log(this.index);
Modificamos el evento click de nuestro html
(click)="verHeroe()"
Agregamos la definición de nuestro nuevo input en el componente
<app-heroe-tarjeta *ngFor="let heroeLocal of heroes; let i = index" [heroeAux]="heroeLocal"
[index]="i"></app-heroe-tarjeta>
Finalmente agrego el ruteo en mi componente tarjeta
import { Component, OnInit, Input } from '@angular/core';
Ing. Gerardo Magni Página 3
Angular
Magni Gerardo
import { Heroe } from '../../servicios/heroes.service';
import { Router } from "@angular/router";
@Component({
selector: 'app-heroe-tarjeta',
templateUrl: './heroe-tarjeta.component.html',
styleUrls: ['./heroe-tarjeta.component.css']
})
export class HeroeTarjetaComponent implements OnInit {
@Input() heroeAux:Heroe;
@Input() index:number;
constructor(private router:Router) { }
ngOnInit() {
}
public verHeroe(){
console.log(this.index);
this.router.navigate(['/heroe', this.index])
}
En este momento hemos logrado que todo funcione, pero haciendo uso de la tarjeta como componente.
PRACTICA @Input
Modifique el componente buscador.component para que haga uso del componente héroe-tarjeta-
component.
Emitir un Evento del Hijo hacia el Padre @Output
Vamos a ejecutar el método verHeroe que existe en el componente héroes.component
public verHeroe(idx:number){
this.router.navigate(['/heroe', idx])
}
Ejecutando una llamada desde el componente hijo heroeTarjeta
Para lograr este objetivo haremos uso del decorador @Output
@Output() heroeSeleccionado:EventEmitter<number>;//number es el index
Ing. Gerardo Magni Página 4
Angular
Magni Gerardo
Nuestro componente héroe-tarjeta toma la siguiente forma
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { Heroe } from '../../servicios/heroes.service';
import { Router } from "@angular/router";
@Component({
selector: 'app-heroe-tarjeta',
templateUrl: './heroe-tarjeta.component.html',
styleUrls: ['./heroe-tarjeta.component.css']
})
export class HeroeTarjetaComponent implements OnInit {
@Input() heroeAux:Heroe;
@Input() index:number;
//entre <> tiene que asignarse el tipo de dato a emitir
//puede ser un object, string, number, etc
@Output() heroeSeleccionado:EventEmitter<number>;//number es el index
constructor(private router:Router) {
this.heroeSeleccionado = new EventEmitter();
}
ngOnInit() {
}
public verHeroe(){
//console.log(this.index);
//this.router.navigate(['/heroe', this.index])
this.heroeSeleccionado.emit(this.index);
}
}
Y nuestro héroes component queda:
<h1>Heroes de Marvel y de DC Comics</h1>
<hr>
<div class="card-columns">
<!--*ngFor="let heroeAux of heroes; let i = index"-->
<app-heroe-tarjeta (heroeSeleccionado)="verHeroe($event)" *ngFor="let heroeLocal of heroes;
let i = index" [heroeAux]="heroeLocal" [index]="i">
</app-heroe-tarjeta>
</div>
Ing. Gerardo Magni Página 5
Angular
Magni Gerardo
Note que hemos agregado el evento
(heroeSeleccionado)="verHeroe($event)"
$event es una palabra reservada de angular que indica que el evento heroeSeleccionado ejecuta un
evento y emite un valor
PRACTICA @Output
Modifique el componente buscador.component para que dispare el evento heroeSeleccionado al
presionar el botón “Ver Mas..” del componente héroe-tarjeta-component.
Nota Ayuda: Una posible solución, en el caso del buscador será modificar el método buscarHeroes de
héroes.service para incluir el índice apropiado del héroe en el arreglo
for(let i=0; i < this.heroes.length; i++){
let heroe = this.heroes[i];
let nombre = heroe.nombre.toLowerCase();
if(nombre.indexOf(termino) >= 0){
heroe.idx = i;
heroesArr.push(heroe);
}
export interface Heroe{
nombre:string;
bio:string;
img:string;
aparicion:string;
casa:string;
idx?:number;//variable opcional
}
Ing. Gerardo Magni Página 6
Angular
Magni Gerardo
PIPES
Transforman el dato solo a nivel visual.
Variable Inicial Pipe Resultado Final
nombre = “Carlos”; {{nombre | uppercase}} CARLOS Todo en mayusculas
nombre = “Carlos”; {{nombre | lowercase}} carlos Todo en minúsculas
nombre = “Carlos”; {{nombre | slice:3}} Los Modifica una cadena o
nombre = “Carlos”; {{nombre | slice:0:3}} Car array según la cantidad
array=[0,1,2,3,4] {{ array | slice:1:3}} 1,2,3 de caracteres indicados
en value (slice:value)
numero=3,14459265 {{ numero | number}} 3,142 Formatea un numero
numero=3,14459265 {{ numero | number:’3.0-0’}} asignando cantidad de
numero=3,14459265 {{ numero | number:’1.0-2’}} enteros y de decimales
numero=0,234 {{ numero | percent}} 23.4% Pasa a porcentaje
salario=1234.5 {{ salario | currency}} U$D 1,234.50 Números a formato
Moneda.
heroe={ {{ heroe | json}} heroe={ Muestre el objeto en
nombre=”Batman”, nombre=”Batman”, formato JSON
ciudad=”Gotica”, ciudad=”Gotica”,
poder=”millonario” poder=”millonario”
} }
fecha = new Date() {{fecha | date}} Jan 25, 2017
{{fecha | date:’medium’}} Jan 25 2017 17:33:33
{{fecha | date:’dd-MM’}} 25-01
Cambiar Pipe de Fecha a Lenguaje Español
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { LOCALE_ID, NgModule } from '@angular/core';
import { AppComponent } from '../src/app/app.component';
import localeEs from '@angular/common/locales/es';
import { registerLocaleData } from '@angular/common';
registerLocaleData(localeEs);
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
providers: [ { provide: LOCALE_ID, useValue: 'es' } ],
Ing. Gerardo Magni Página 7
Angular
Magni Gerardo
bootstrap: [ AppComponent ]
})
export class AppModule { }
Ing. Gerardo Magni Página 8
Angular
Magni Gerardo
Trabajo Práctico Angular – Componentes, Servicios, Rutas, Input, Output
Dada la siguiente Imagen:
Leyendas del Futbol
Zidane Distefano Beckenbauer Cruyff Critiano Ronaldo
(mediocampista) (mediocampista) (defensor) (mediocampista) (delantero)
Messi (delantero) Ronaldo Ronaldhino Pele (delantero) Maradona
(delantero) (mediocampista) (mediocampista)
Genere un sitio Angular que permita visualizar los datos de cada una de las leyendas del futbol de
contenidas en la imagen anterior como una tarjeta de futbol individual. (Deberá crear una imagen por cada
jugador para usar en c/tarjeta)
Cree una interfaz jugador que posea los siguientes atributos:
Nombre:string
Nacionalidad:string
fechaNacimiento:date
posición:string (defensor, mediocampista, delantero)
Ing. Gerardo Magni Página 9
Angular
Magni Gerardo
Agregue a cada tarjeta un botón para mostrar el detalle del jugador seleccionado mostrando una pequeña
biografía del mismo en el componente detalle-jugador (busque en internet, wikipedia la biografia)
Finalmente agregue al componente principal del sitio un combo con las opciones de posición que permita
filtrar los jugadores que pertenezcan a dicha posición.
Ing. Gerardo Magni Página 10