Está en la página 1de 139

JAVA DEVELOPER

SESION 14
Angular

Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Introducción

Angular 2
● Angular es un framework para desarrollo SPA
● Permite extender el HTML con etiquetas propias
● Con aspecto personalizado (HTML,CSS)
● Con comportamiento personalizado (JavaScript)
● Interfaz basado en componentes (no en páginas)
● Se recomienda usar con TypeScript (aunque se
puede con ES5 y ES6)
● Inyección de dependencias
https://angular.io/ 12
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Introducción

Angular 2 vs Angular 1
● Acaba de publicarse la versión final (Sept 2016)
● Está implementado desde cero, no como una
evolución de Angular 1
● Angular 2 no es compatible con Angular 1
● Cuidado, la documentación de Angular 1 no sirve
paraAngular 2

$scope
3
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Introducción

Lenguaje programación Angular 2


● Angular 2 tiene soporte oficial para desarrollo
de apps con JavaScript (ES5 y ES6) y
TypeScript
● Se puede usar cualquier lenguaje que transpile
a JavaScript

ES5 ES6
4
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Introducción

Lenguaje programación Angular 2


● Angular 2 tiene soporte oficial para desarrollo
de apps con JavaScript (ES5 y ES6) y
TypeScript
● Se puede usar cualquier lenguaje que transpile
a JavaScript

ES5 ES6
5
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Introducción

Funcionalidades de Angular 2
● Inyección de dependencias
● Servicios
● Cliente http (APIs REST)
● Navegación por la app (Router)
● Animaciones
● Internacionalización
● Soporte para tests unitarios y e2e
● Librerías de componentes: Material Design
● Renderizado en el servidor
● ...
6
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Angular 2

● Introducción a Angular 2
● TypeScript
● Herramientas de desarrollo
● Componentes
● Templates
● Composición de componentes
● Cliente REST e inyección de dependencias
● Servicios
● Aplicaciones multipágina: Router
● Librerías de componentes
● Conclusiones
7
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Características
● Añade tipos estáticos a JavaScript ES6
● Inferencia de tipos (no hay que declararlos en muchos sitios)

Tipos opcionales (si no quieres, no los usas)
● El compilador genera código JavaScript ES5
(compatible con los navegadores web actuales)
● Orientado a Objetos con clases (no como ES5)
● Anotaciones
http://www.typescriptlang.org/
https://www.gitbook.com/book/basarat/typescript/details
18
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Ventajas frente a JavaScript


● Con el tipado estático el compilador puede verificar
la corrección de muchas más cosas que con el
tipado dinámico
● Los programas grandes son menos propensos a
errores
● Los IDEs y editores pueden:Autocompletar,
Refactorizar, Navegar a la definición
● Muy parecido a Java yC#
9
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Facilidad de adopción para JavaScripters


● Los tipos son opcionales
● La inferencia de tipos permite no tener que
escribir los tipos constantemente
● En realidad es JavaScript con más cosas, así que
todo lo conocido se puede aplicar
● Un mismo proyecto puede combinar JS yTS, lo
que facilita migrar un proyecto existente

10
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript
export class Empleado { TypeScript

private nombre:string;
private salario:number;

constructor(nombre:string,salario:number){
this.nombre = nombre;
this.salario = salario;
}

getNombre(){
return this.nombre;
}

toString(){
return "Nombre:"+this.nombre+
", Salario:"+this.salario;
}
}
11
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

ClasesTypeScript vs JavaScript ES5


Clase enTypeScript Simulación de clase en JS ES5 con prototipos
export class Empleado {

private nombre:string;
private salario:number;

constructor(nombre:string, function Empleado(nombre, salario){


salario:number){
this.nombre = nombre; this.nombre = nombre;
this.salario = salario; this.salario = salario;
} }

getNombre(){ Empleado.prototype.getNombre = function(){


return this.nombre; return this.nombre;
} };

toString(){ Empleado.prototype.toString = function(){


return "Nombre:"+this.nombre+ return "Nombre:"+this.nombre+",
", Salario:"+this.salario; Salario:"+this.salario;
} };
} 22
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Clases Java vs TypeScript


Clase en Java Clase enTypeScript
public class Empleado { export class Empleado {

private String nombre; private nombre:string;


private double salario; private salario:number;

public Empleado(String nombre, constructor(nombre:string,


double salario){ salario:number){
this.nombre = nombre; this.nombre = nombre;
this.salario = salario; this.salario = salario;
} }

public String getNombre(){ getNombre(){


return nombre; return this.nombre;
} }

public String toString(){ toString(){


return "Nombre:"+nombre+ return "Nombre:"+this.nombre+
", Salario:"+salario; ", Salario:"+this.salario;
} }
} }
23
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Clases Java vs TypeScript


Clase en Java Clase enTypeScript
public class Empleado { export class Empleado {

private String nombre; private nombre:string;


private double salario; private salario:number;

public Empleado(String nombre, constructor(nombre:string,


double salario){ salario:number){
this.nombre = nombre; this.nombre = nombre;
this.salario = salario; this.salario = salario;
} }

public String getNombre(){ getNombre(){


return nombre; return this.nombre;
} }

public String toString(){ toString(){


return "Nombre:"+nombre+ return "Nombre:"+this.nombre+
", Salario:"+salario; ", Salario:"+this.salario;
} }
} En Java las clases son públicas. EnT}ypeScriptlas clases se exportan 24
Av. Arenales 395 Oficin a 405 - 4336948 - info@cjavaperu.com CJava, siempre para a poyarte.
TypeScript

Clases Java vs TypeScript


Clase en Java Clase enTypeScript
public class Empleado { export class Empleado {

private String nombre; private nombre:string;


private double salario; private salario:number;

public Empleado(String nombre, constructor(nombre:string,


double salario){ salario:number){
this.nombre = nombre; this.nombre = nombre;
this.salario = salario; this.salario = salario;
} }

public String getNombre(){ getNombre(){


return nombre; return this.nombre;
} }

public String toString(){ toString(){


return "Nombre:"+nombre+ return "Nombre:"+this.nombre+
", Salario:"+salario; ", Salario:"+this.salario;
} }
} EnTS los tipos se ponen tras e}lnombre con : (dos puntos) 25
Av. Arenales 395 Oficin a 405 - 4336948 - info@cjavaperu.com CJava, siempre para a poyarte.
TypeScript

Clases Java vs TypeScript


Clase en Java Clase enTypeScript
public class Empleado { export class Empleado {

private String nombre; private nombre:string;


private double salario; private salario:number;

public Empleado(String nombre, constructor(nombre:string,


double salario){ salario:number){
this.nombre = nombre; this.nombre = nombre;
this.salario = salario; this.salario = salario;
} }

public String getNombre(){ getNombre(){


return nombre; return this.nombre;
} }

public String toString(){ toString(){


return "Nombre:"+nombre+ return "Nombre:"+this.nombre+
", Salario:"+salario; ", Salario:"+this.salario;
} }
} EnTS el constructo}r es “constructor” 26
Av. Arenales 395 Oficina 405 - 4336948 - in fo@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Clases Java vs TypeScript


Clase en Java Clase enTypeScript
public class Empleado { export class Empleado {

private String nombre; private nombre:string;


private double salario; private salario:number;

public Empleado(String nombre, constructor(nombre:string,


double salario){ salario:number){
this.nombre = nombre; this.nombre = nombre;
this.salario = salario; this.salario = salario;
} }

public String getNombre(){ getNombre(){


return nombre; return this.nombre;
} }

public String toString(){ toString(){


return "Nombre:"+nombre+ return "Nombre:"+this.nombre+
", Salario:"+salario; ", Salario:"+this.salario;
} }
} EnTS los tipos se infieren (si quieres), inc}lusoen el tipo que devuelven losmétodos 27
Av. Arenales 39 5 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Clases Java vs TypeScript


Clase en Java Clase enTypeScript
public class Empleado { export class Empleado {

private String nombre; private nombre:string;


private double salario; private salario:number;

public Empleado(String nombre, constructor(nombre:string,


double salario){ salario:number){
this.nombre = nombre; this.nombre = nombre;
this.salario = salario; this.salario = salario;
} }

public String getNombre(){ getNombre(){


return nombre; return this.nombre;
} }

public String toString(){ toString(){


return "Nombre:"+nombre+ return "Nombre:"+this.nombre+
", Salario:"+salario; ", Salario:"+this.salario;
} }
} } 28
EnTS siembre que quieras acceder a un elemento
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com
de la clase tendrás que usar this.
CJava, siempre para apoyarte.
TypeScript
TypeScript
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();

emps.push(new Empleado('Pepe', 500));


emps.push(new Empleado('Juan', 200));
for(let emp of emps){
console.log(emp.getNombre());
}

empleados.forEach(emp => {
console.log(emp);
});
19
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Imports / Listas / foreach / lambdas


Java TypeScript
import { Empleado } from "./Empleado";
List<Empleado> emps = new ArrayList<>(); let emps = new Array<Empleado>();

emps.add(new Empleado('Pepe', 500)); emps.push(new Empleado('Pepe', 500));


emps.add(new Empleado('Juan', 200)); emps.push(new Empleado('Juan', 200));

for(Empleado emp : emps){ for(let emp of emps){


System.out.println(emp.getNombre()); console.log(emp.getNombre());
} }

empleados.forEach(emp -> { empleados.forEach(emp => {


System.out.println(emp); console.log(emp);
}); });

20
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Imports / Listas / foreach / lambdas


Java TypeScript
import { Empleado } from "./Empleado";

List<Empleado> emps = new ArrayList<>(); let emps = new Array<Empleado>();

emps.add(new Empleado('Pepe', 500)); emps.push(new Empleado('Pepe', 500));


emps.add(new Empleado('Juan', 200)); emps.push(new Empleado('Juan', 200));

for(Empleado emp : emps){ for(let emp of emps){


System.out.println(emp.getNombre()); console.log(emp.getNombre());
} }

empleados.forEach(emp -> { empleados.forEach(emp => {


System.out.println(emp); console.log(emp);
}); });

En Java las clases de la misma carpeta son del mismo paquete.


EnTS cada fichero es un módulo, por eso hay que importar desde otros ficheros
31
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Imports / Listas / foreach / lambdas


Java TypeScript
import { Empleado } from "./Empleado";

List<Empleado> emps = new ArrayList<>(); let emps = new Array<Empleado>();

emps.add(new Empleado('Pepe', 500)); emps.push(new Empleado('Pepe', 500));


emps.add(new Empleado('Juan', 200)); emps.push(new Empleado('Juan', 200));

for(Empleado emp : emps){ for(let emp of emps){


System.out.println(emp.getNombre()); console.log(emp.getNombre());
} }

empleados.forEach(emp -> { empleados.forEach(emp => {


System.out.println(emp); console.log(emp);
}); });

EnTS las variables se declaran con let y tienen ámbito de bloque y no se pueden declarar dos
veces. Se podría usar var (como JS), pero el ámbito sería la función y se podrían redeclarar
32
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Imports / Listas / foreach / lambdas


Java TypeScript
import { Empleado } from "./Empleado";

List<Empleado> emps = new ArrayList<>(); let emps = new Array<Empleado>();

emps.add(new Empleado('Pepe', 500)); emps.push(new Empleado('Pepe', 500));


emps.add(new Empleado('Juan', 200)); emps.push(new Empleado('Juan', 200));

for(Empleado emp : emps){ for(let emp of emps){


System.out.println(emp.getNombre()); console.log(emp.getNombre());
} }

empleados.forEach(emp -> { empleados.forEach(emp => {


System.out.println(emp); console.log(emp);
}); });

EnTS las variables se pueden declarar con tipo (después de :), pero es opcional porque el tipo
se infiere de la inicialización. En Java no lo veremos hasta Java 9 o Java 10
33
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Imports / Listas / foreach / lambdas


Java TypeScript
import { Empleado } from "./Empleado";

List<Empleado> emps = new ArrayList<>(); let emps = new Array<Empleado>();

emps.add(new Empleado('Pepe', 500)); emps.push(new Empleado('Pepe', 500));


emps.add(new Empleado('Juan', 200)); emps.push(new Empleado('Juan', 200));

for(Empleado emp : emps){ for(let emp of emps){


System.out.println(emp.getNombre()); console.log(emp.getNombre());
} }

empleados.forEach(emp -> { empleados.forEach(emp => {


System.out.println(emp); console.log(emp);
}); });

En Java usamos List y ArrayList generificados delAPI.


EnTS usamos el Array nativo de JS generificado porTS.
34
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Imports / Listas / foreach / lambdas


Java TypeScript
import { Empleado } from "./Empleado";

List<Empleado> emps = new ArrayList<>(); let emps = new Array<Empleado>();

emps.add(new Empleado('Pepe', 500)); emps.push(new Empleado('Pepe', 500));


emps.add(new Empleado('Juan', 200)); emps.push(new Empleado('Juan', 200));

for(Empleado emp : emps){ for(let emp of emps){


System.out.println(emp.getNombre()); console.log(emp.getNombre());
} }

empleados.forEach(emp -> { empleados.forEach(emp => {


System.out.println(emp); console.log(emp);
}); });

En Java List el método es “add”


En el array de JS el método es “push”
35
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Imports / Listas / foreach / lambdas


Java TypeScript
import { Empleado } from "./Empleado";

List<Empleado> emps = new ArrayList<>(); let emps = new Array<Empleado>();

emps.add(new Empleado('Pepe', 500)); emps.push(new Empleado('Pepe', 500));


emps.add(new Empleado('Juan', 200)); emps.push(new Empleado('Juan', 200));

for(Empleado emp : emps){ for(let emp of emps){


System.out.println(emp.getNombre()); console.log(emp.getNombre());
} }

empleados.forEach(emp -> { empleados.forEach(emp => {


System.out.println(emp); console.log(emp);
}); });

La sintaxis del foreach es muy parecida en Java yTS.


EnTS está basado en iteradores (como enJava)
36
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Imports / Listas / foreach / lambdas


Java TypeScript
import { Empleado } from "./Empleado";
List<Empleado> emps = new ArrayList<>(); let emps = new Array<Empleado>();

emps.add(new Empleado('Pepe', 500)); emps.push(new Empleado('Pepe', 500));


emps.add(new Empleado('Juan', 200)); emps.push(new Empleado('Juan', 200));

for(Empleado emp : emps){ for(let emp of emps){


System.out.println(emp.getNombre()); console.log(emp.getNombre());
} }

empleados.forEach(emp -> { empleados.forEach(emp => {


System.out.println(emp); console.log(emp);
}); });

Las expresiones lambda de Java se llaman arrow function enTS.


Se diferencian en la “flecha” con – o con =
37
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Uso de this con la arrow function


JavaScript TypeScript

function Empleado(nombre, sueldo){ export class Empleado {


this.nombre = nombre;
this.sueldo = sueldo; constructor(
} private nombre:string,
private sueldo:number){}
Empleado.prototype.alerta(button){
var that = this; alerta(button:HTMLButtonElement){
button.onclick = function(e){ button.onclick = e => {
alert(that.nombre); alert(this.nombre);
} }
} }
}

EnTypeScript una arrow function permite usar this y siempre


apunta al objeto, no al evento (no es necesario usar that)
28
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Lambdas / Arrow functions


Java TypeScript
int num = 0; let num = 0;

empleados.forEach(emp -> num++); empleados.forEach(emp => num++);

System.out.println(num); console.log(num);
ERROR

En Java no se puede acceder a una variable que no sea final (declarada o


efectiva) desde una lambda. EnTS (como en JS) incluso se puede
cambiar el valor de la variable desde la propia arrow function

29
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript
Uso de this con la arrow function
JavaScript TypeScript

function Empleado(nombre, sueldo){ export class Empleado {


this.nombre = nombre;
this.sueldo = sueldo; private nombre:string,
} private sueldo:number){}

Empleado.prototype.alerta(button){ alerta(button:HTMLButtonElement){
var that = this; button.onclick = e => {
button.onclick = function(e){ alert(this.nombre);
alert(that.nombre); }
} }
} }

EnTS una arrow function permite usar this y siempre apunta al objeto
(como Java). En JS, dentro del una función this puede cambiar de valor
(y es necesario usar that para referirse al objeto)
30
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Anotaciones

import {Component} from 'angular2/core';


@Component({
selector: 'app',
templateUrl: 'app.component.html'
})
export class AppComponent {

31
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Definición de atributos en el constructor


class Animal {

private name:string;

constructor(name: string) {
this.name = name;
}
}

32
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Definición de atributos en el constructor


class Animal {
private name:string;
constructor(name: string) {
this.name = name;
}
}

class Animal {
constructor(private name: string) {
}
}
En TS se puede declarar un atributo e inicializar su valor desde el constructordeclarando
ese atributo como parámetro del constructor y usando el modificar de visibilidad 43
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Getter / Setter con sintaxis de atributo


class Foo {

get bar() {
return ...; let foo = new Foo();
}
if(foo.bar){
set bar(bar: boolean) { foo.bar = false;
... }
}
}

34
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Getter / Setter con sintaxis de atributo


class Foo {

get bar() {
return ...; let foo = new Foo();
}
if(foo.bar){
set bar(bar: boolean) { foo.bar = false;
... }
}
}

35
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript
Type guards Instanceof / typeof
class Animal { eat() { } }
Animal class Dog extends Animal { woof() { } }
class Cat extends Animal { meow() { } }
eat()
let pet: Animal = ...;
if (pet instanceof Dog) {
ADniomgal AnCiamtal pet.woof();
weoaot(f)() meeaotw()() } else if (pet instanceof Cat) {
pet.meow();
} else {
pet.eat();
} Disponible también en

46
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Objetos literales “tipados”

interface SquareConfig {
color: string;
width?: number;
}

let config: SquareConfig;

config = {color: "black"};


config = {color: "black", width: 20};

37
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Objetos literales “tipados”

interface SquareConfig {
color: string;
width?: number;
}

let config: SquareConfig;

config = {color: "black"};


config = {color: "black", width: 20};

38
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript
Programación asíncrona
Simulación de sincronía con async / await
function loadData() { async function loadData() {
return getJSON('data.json') try {
.then(data=>{
let data =
addHtmlToPage(data); await getJSON('data.json');

return data; addHtmlToPage(data);


return data;
}).catch(err => {
console.log(err) } catch(err){
}); console.log(err);
} }
}
De momento sólo disponible cuando se genera código ES6 desde TS 39
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript
Programación asíncrona
Simulación de sincronía con async / await
function loadData() { async function loadData() {
return getJSON('data.json') try {
.then(data=>{
let data =
addHtmlToPage(data); await getJSON('data.json');

return data; addHtmlToPage(data);


return data;
}).catch(err => {
console.log(err) } catch(err){
}); console.log(err);
} }
}
De momento sólo disponible cuando se genera código ES6 desdeTS 50
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Tipos unión
let id: string | number;

id = 3; En JS es habitual que ciertas


... variables puedan tener la misma
Id = “3”; información aunque se
represente con varios “tipos”.
TS permite definir variables con
if(typeof id === “string”){ varios tipos
...
}

41
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Compatibilidad de tipos estructural


interface User {
name: string;
}

class Profile {
constructor(public name:string){}
}

let u: User;
u = { name: "Pepe" };
u = new Profile("Pepe");
42
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Compatibilidad de tipos estructural


interface User {
name: string;
}

class Profile {
constructor(public name:string){}
}

let u: User; Un objeto Profile puede


u = { name: "Pepe" }; asignarse a una variabl e
u = new Profile("Pepe"); de tipo User porque tiene
un atributo name
43
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Sobrecarga de métodos “especial”


class TestClass {

someMethod(p1: string): void;


someMethod(p1: number, p2: string): void;

someMethod(p1: string | number, p2?: string): void {

if (typeof p1 === "string"){


console.log("p1");
} else if(p2){ Dos métodos con el mismo
console.log("p2"); nombre deben tener una única
}
implementación que detecte cu al
}
ha sido llamado.
} La implementación tiene que
cubrir todas las cabeceras 54
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
TypeScript

Editores / IDEs
Hay plugins para la mayoría de los editores / IDEs

SublimeText VisualStudio
WebStorm
Code

55
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
WebStorm 11
WebStorm 11
WebStorm 11
Atom / atom-typescript

https://atom.io/packages/atom-typescript
TypeScript

Popularidad deTypeScript

TypeScript
coffeescript
ES6

50
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Angular 2

● Introducción a Angular 2
● TypeScript
● Herramientas de desarrollo
● Componentes
● Templates
● Composición de componentes
● Cliente REST e inyección de dependencias
● Servicios
● Aplicaciones multipágina: Router
● Librerías de componentes
● Conclusiones
51
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

Angular2 con un editor


● Es posible desarrollar aplicaciones angular 2
únicamente con un editor y un servidor web
(p.e. brackets)
● Inconvenientes
● El código tarda más en cargarse y en ejecutarse
● Notificación de errores mucho más limitada
● Sin autocompletar ni navegación entre los
elementos del código
52
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

Plataforma y gestión de paquetes

Plataforma para
ejecutar aplicaciones JS
fuera del navegador

Gestor de herramientas
de desarrollo y librerías
JavaScript (integrado
con node.js)

53
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

Instalación node.js y npm


● Para usar las herramientas de desarrollo deAngular 2 es
necesario instalar node.js 4 o superior
● Instalación windows y mac
https://nodejs.org/en/download/stable/
● Instalación linux
https://nodejs.org/en/download/package-manager/
● Ubuntu
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo apt-get install -y nodejs-legacy
54
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

Construcción de proyectos / empaquetado


● Existen muchas herramientas para

procesar los fuentes de la aplicación


● Objetivos:

● Reducción del tiempo de descarga


● PreprocesadoresCSS
● Optimización del código, CSS, HTML
● Cumplimiento de estilos y generación de JavaScript

55
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

Construcción de proyectos / empaquetado

http://gulpjs.com/ http://broccolijs.com/

http://gruntjs.com/ https://webpack.github.io/
56
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

Generación de código esqueleto


● No se suele crear un proyecto desde cero
porque hay muchos ficheros y carpetas que
son muy parecidos en todos los proyectos
● Existen muchos enfoques para conseguir el
esqueleto inicial de una web SPA
● Nos centraremos en los específicos para
Angular 2
57
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

Generación de código esqueleto


● Generadores basados en Yeoman
● Proyectos semilla (seed) disponibles en github
● Herramienta oficial de gestión de proyectos

58
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

Generación de código esqueleto


● Generadores de códigoAngular 2 no oficiales
basados en Yeoman
● https://www.npmjs.com/package/generator-modern-web-dev
● https://www.npmjs.com/package/generator-angular2
● https://www.npmjs.com/package/generator-gulp-angular2
● https://github.com/joshuacaron/generator-angular2-gulp-webpack
● https://www.npmjs.com/package/slush-angular2

NOTA: Es conveniente verificar si están


actualizados a la última versión de Angular 2.
Pueden estar desactualizados
59
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

Generación de código esqueleto


● Proyectos semilla (seed) disponibles en github
● http://mgechev.github.io/angular2-seed/
● https://github.com/ghpabs/angular2-seed-project
● https://github.com/cureon/angular2-sass-gulp-boilerplate
● https://angularclass.github.io/angular2-webpack-starter/
● https://github.com/LuxDie/angular2-seed-jade
● https://github.com/justindujardin/angular2-seed

NOTA: Es conveniente verificar si están


actualizados a la última versión de Angular 2.
Pueden estar desactualizados
60
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

Generación de código esqueleto


● Herramienta oficial de gestión de proyectos
● https://github.com/angular/angular-cli
● Ofrece comandos para:
● Generación del proyecto inicial
● Generación de partes posteriormente
● Modo desarrollo con compilado automático de
TypeScript y actualización del navegador
● Construcción del proyecto para distribución (build)
61
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

● Herramienta oficial angular-cli


● Instalación
● Pueden ser necesarios permisos de administrador

npm install -g angular-cli

● Generación del proyecto


● Se descargarán 250Mb de Internet y se configurarán las
herramientas. Puede tardar bastante tiempo.

ng new ejem1
cd ejem1
62
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

● Herramienta oficial angular-cli

https://karma-runner.github.io

http://jasmine.github.io/

https://webpack.github.io/
Construcción http://www.protractortest.org/
del proyecto
Herramientas de testing 73
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

● Herramienta oficial angular-cli


● Ejecutar servidor web en modo desarrollo
● Se iniciará un servidor web en http://localhost:4200
● Hay que abrir el navegador para ejecutar la app
● Al guardar un fichero fuente, la aplicación se recargará
automáticamente
● El código TypeScript que transpilará aJavaScript
automáticamente
ng serve

● EnWindows es mejor ejecutar el comando como


administrador para que vaya más rápido 64
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

65
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

● Ficheros/Carpetas
generadas
● E2e: Testing end to end
● dist: Recursos que hay que
publicar en el servidor web
● node_modules: Librerías y
herramientas descargadas
● src: Fuentes de la aplicación
● package.json:
Configuración de librerías y
herramientas

66
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

● Ficheros/Carpetas generadas
● src/app:
● Carpeta que contiene los ficheros fuente
principales de la aplicación.
● Borraremos su contenido y le sustituiremos por
los ejemplos
● main.ts: Fichero principal de la aplicación. No
es necesario modificarle
● favicon.ico: Icono de la aplicación
● index.html: Página principal. Se editará para
incluir CSS globales en la web (bootstrap)
● tsconfig.json: Configuración del compiladorTS
67
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

● Actualización del mensaje de la app


app.component.html

Al guardar un fichero el
<h1> navegador se recarga de
{ { t i t l e}} forma automática y
</ h1> vemos los cambios

app.component.html

<h1>
{ { t i t l e} }
</ h1>

Hola caracola!
68
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

● Herramienta oficial angular-cli


● Generar el contenido para publicar en producción
● Cuando queremos publicar la aplicación en producción
tenemos que generar los archivos optimizados y
publicarlos en un servidor web
● Usamos el comando
ng build

● Genera los ficheros en la carpeta dist


● De momento no optimiza el resultado (main.bundle.js
ocupa 2,5 megas), pero en la versión final de angular-cli
podrá llegar a 50Kb
69
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

● Optimización de espacio en disco


● Para tener varias aplicaciones, podemos copiar la
carpeta main completa y cambiar los ficheros de
src\app
● La carpeta node_modules ocupa unos 250Mb,
pero es la misma para todas las aplicaciones
● La podemos compartir entre apps si está en la
carpeta padre de todas las apps
● NPM busca los paquetes en la carpeta actual o en
las carpetas padre
70
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Herramientas de desarrollo

● Optimización de espacio en disco


● Si borramos la carpeta node_modules la podemos
regenerar descargando de nuevo las librerías de
Internet
npm install

● Si compartimos el proyecto en git, la carpeta


node_modules se ignora. Para regenerarla
ejecutamos npm install después de clonar el
proyecto.
71
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Angular 2

● Introducción a Angular 2
● TypeScript
● Herramientas de desarrollo
● Componentes
● Templates
● Composición de componentes
● Cliente REST e inyección de dependencias
● Servicios
● Aplicaciones multipágina: Router
● Librerías de componentes
● Conclusiones
72
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes

Componentes en Angular 2
● Un componente es una nueva etiqueta HTML
con una vista y una lógica definidas por el
desarrollador
● La vista es una plantilla (template) en HTML
con elementos especiales
● La lógica es una claseTypeScript vinculada a
la vista
73
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes

Componentes en Angular 2
● Copiamos el contenido de la carpeta src/app
del ejem1

74
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem1
Componentes en Angular 2

app.component.ts

import { Component } from '@angular/core';

app.component.html
@Component({
selector: 'app-root', <h1>My First Angular 2 App</h1>
templateUrl: './app.component.html'
})
export class AppComponent {
}

Lógica Vista
75
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem1
Componentes en Angular 2

app.component.ts

import { Component } from '@angular/core';

app.component.html
@Component({
selector: 'app-root', <h1>My First Angular 2 App</h1>
templateUrl: './app.component.html'
})
export class AppComponent {
}

Lógica Vista
76
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem1
Componentes en Angular 2

app.component.ts

import { Component } from '@angular/core';

@Component({ app.component.html
selector: 'app-root',
templateUrl: './app.component.html' <h1>My First Angular 2 App</h1>
})
export class AppComponent {
}
Este componente no
tiene ninguna lógica

Lógica Vista
77
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
app.component.ts ejem1
import { Component } from '@angular/core';

@Component({ app.component.html
selector: 'app-root',
templateUrl: './app.component.html' <h1>My First Angular 2 App</h1>
})
export class AppComponent {
}
Para usar el componente se
incluye en el index.html un
elemento HTML con el
src/index.html nombre indicado en el selector
<html> (en este caso app-root)
<head>...</head>
<body>
<app-root>Loading...</app-root>
</body>
</html>

78
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem1
Componentes en Angular 2
Toda app tiene un módulo que define los
componentes de la app, el componente principal y
qué otros módulos necesita
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

@NgModule({ Componentes declarados


declarations: [AppComponent],
imports: [BrowserModule, FormsModule], Módulos importados
bootstrap: [AppComponent]
})
export class AppModule { } Componente principal
79
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem1
Fichero índice de la carpeta
EnTS se pueden definir ficheros index.ts que exportan todos los
ficheros de una carpeta. Eso simplifica la importación desde otros
ficheros y desacopla los tipos del fichero en el que se declaran
index.ts

export * from './app.component'; Fichero que lista todos los


export * from './app.module'; ficheros TS de unacarpeta

src/main.ts Al importar ese fichero se


puede referenciar
import { AppModule } from './app/'; cualquier clase de la
carpeta (similara
//... paquetes Java)
80
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem1

81
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem1
Componentes en Angular 2
app.component.ts

import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: ` Se puede incluir la vista (HTML
<h1> del template) directamente en
My First Angular 2 App la clase. Si se usa la tildes
</h1> invertidas ( `) (grave accent),se
` puede escribir HTML multilínea
})
export class AppComponent {
}
82
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem2
Visualización de una variable
La vista del componente (HTML) se genera en función
de su estado (atributos de la clase)
app.component.ts app.component.html

import { Component } from <h1>Hello {{name}}!</h1>


'@angular/core'; <img [src]="imgUrl"/>

@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
name = 'Anybody';
imgUrl = "assets/img.png";
}
83
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem2
Visualización de una variable
La vista del componente (HTML) se genera en función
de su estado (atributos de la clase)
app.component.ts app.component.html

import { Component } from <h1>Hello {{name}}!</h1>


'@angular/core'; <img [src]="imgUrl"/>

@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
name = 'Anybody';
imgUrl = "assets/img.png";
}
84
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem2
Recursos de la app
Los recursos (imágenes, fonts..) deben colocarse en
una carpeta src/assets para que se copien en el build

85
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem3
Ejecución de lógica
Se puede ejecutar un método ante un evento
producido en la vista del componente
app.component.ts
import {Component} from '@angular/core';

@Component({
selector: 'app',
templateUrl: './app.component.html'
})
export class AppComponent { app.component.html

name = 'Anybody'; <h1>Hello {{name}}!</h1>

setName(name:string){ <button (click)="setName('John')">


this.name = name; Hello John
} </button>
} 96
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem3
Ejecución de lógica
Se puede ejecutar un método ante un evento
producido en la vista del componente
app.component.ts
import {Component} from '@angular/core';

@Component({
selector: 'app',
templateUrl: './app.component.html'
})
export class AppComponent { app.component.html

name = 'Anybody'; <h1>Hello {{name}}!</h1>

setName(name:string){ <button (click)="setName('John')">


this.name = name; Hello John
} </button>
} 97
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem3
Ejecución de lógica
Se puede ejecutar un método ante un evento
producido en la vista del componente
app.component.ts
Se puede definir cualquier
import {Component} from '@angular/core';
evento disponible en el
@Component({ DOM para ese elemento
selector: 'app',
templateUrl: './app.component.html'
})
export class AppComponent { app.component.html

name = 'Anybody'; <h1>Hello {{name}}!</h1>

<button (click)="setName('John')">
setName(name:string){
this.name = name; Hello John
} </button>
} 98
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem3
Ejecución de lógica
Se puede ejecutar un método ante un evento
producido en la vista del componente

99
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem4
Datos enlazados (data binding)
Un campo de texto se puede “enlazar” a un atributo
Atributo y componente están sincronizados
app.component.ts
import {Component} from '@angular/core';

@Component({
selector: 'app', app.component.html
templateUrl: './app.component.html '
}) <input type="text" [(ngModel)]="name">
export class AppComponent {
<h1>Hello {{name}}!</h1>
name = 'Anybody';
<button (click)="setName('John')">
setName(name:string){ Hello John
this.name = name; </button>
}
} 100
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem4
Datos enlazados (data binding)
Un campo de texto se puede “enlazar” a un atributo
Atributo y componente están sincronizados
app.component.ts
import {Component} from '@angular/core';

@Component({
selector: 'app', app.component.html
templateUrl: './app.component.html '
}) <input type="text" [(ngModel)]="name">
export class AppComponent {
<h1>Hello {{name}}!</h1>
name = 'Anybody';
<button (click)="setName('John')">
setName(name:string){ Hello John
this.name = name; </button>
}
} 101
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Componentes
ejem4
Datos enlazados (data binding)
Un campo de texto se puede “enlazar” a un atributo
Atributo y componente están sincronizados

92
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Angular 2

● Introducción a Angular 2
● TypeScript
● Herramientas de desarrollo
● Componentes
● Templates
● Composición de componentes
● Cliente REST e inyección de dependencias
● Servicios
● Aplicaciones multipágina: Router
● Librerías de componentes
● Conclusiones
93
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Templates

● Los templates permiten definir la vista en


función de la información del componente
● Visualización condicional
● Repetición de elementos
● Estilos
● Formularios

https://angular.io/docs/ts/latest/guide/template-syntax.html
94
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Templates
ejem5
● Visualización condicional
● Se puede controlar si un elemento aparece o no en
la página dependiendo del valor de un atributo de
la clase usando la directiva ngIf
● Por ejemplo dependiendo del valor del atributo
booleano visible
<p *ngIf="visible">Text</p>

● También se puede usar una expresión


<p *ngIf="num == 3">Num 3</p>
95
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Templates
ejem5
● Repetición de elementos
● Es posible visualizar el contenido de un array con
la directiva ngFor
● Se define cómo se visualizará cada elemento
<div *ngFor="let elem of elems">{{elem.desc}} </div>

items = [
{ desc: 'Elem1', check: true }, <div>Elem1</div>
{ desc: 'Elem2', check: true }, <div>Elem2</div>
{ desc: 'Elem3', check: false } <div>Elem3</div>
]

96
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Templates
ejem5
● Directivas
● Las directivas modifican a los elementos en los que
se incluyen
● Existen muchas directivas predefinidas y podemos
programar nuestras propias directivas
● Las directivas estructurales empiezan por * y
modifican el DOM del documento (*ngIf, *ngFor,
*ngSwitch)
● El * es azúcar sintáctico para la definición del
template
97
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Templates
ejem5
● Directivas
● No se pueden incluir dos directivas estructurales (de tipo *) en
el mismo elemento
<li *ngFor="let elem of elems" *ngIf="elem.check">
{{elem.desc}}
</li>

● Hay que usar la versión de las directivas sin el azúcar


sintáctico (*), en su versión extendida con el elemento
template (que no aparece en el DOM)
<template ngFor let-elem [ngForOf]="elems">
<li *ngIf="elem.check">{{elem.desc}}</li>
</template>

https://github.com/angular/angular/issues/4792 108
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Templates
ejem5
● Estilos
● Existen varias formas de definir un CSS en
Angular 2
● Globalmente asociado al index.html
● Local al componente:
● En la propiedad styles o styleUrls de
@Component
● En el template

99
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Templates
ejem5
● Estilos
● Globalmente asociado al index.html
● Podemos modificar manualmente el fichero
index.html y asociar un CSS (como haríamos con
cualquier HTML)
● Con angular-cli, si creamos un fichero
src/styles.css se incluirá de forma automática en
el index.html

https://github.com/angular/angular-cli#global-styles
100
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Templates
ejem5
● Estilos
● En la propiedad styles o styleUrls de @Component
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styles: [`
.red { color: red; }
.blue { color: blue; } Se suelen usar los strings
`] multilínea con tildes
invertidas
})
export class AppComponent {
...
}

http://blog.thoughtram.io/angular/2015/06/25/styling-angular-2-components.htm1l11
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Templates
ejem5
● Estilos
● En la propiedad styles o styleUrls de @Component
@Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
...
}

Con angular-cli no se puede usar styles y styleUrls a


la misma vez en un component
http://blog.thoughtram.io/angular/2015/06/25/styling-angular-2-components.htm1l12
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Templates
ejem5
● Estilos
● En el template
<style>
.orange {
color: orange;
}
</style>

<h1 [class]="className">Hello {{name}}!</h1>

<button (click)="setClass('blue')">Blue</button>
...

http://blog.thoughtram.io/angular/2015/06/25/styling-angular-2-components.htm1l13
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Templates
ejem5
● Estilos
● Hay muchas formas de controlar los estilos de los
elementos
● Asociar la clase de un elemento a un atributo de tipo
string
● Activar una clase concreta con un atributo boolean
● Asociar la clase de un elemento a un atributo de tipo
mapa de string a boolean
● Asociar un estilo concreto de un elemento a un atributo

104
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Estilos
ejem5
● Asociar la clase de un elemento a un
atributo string
● Cambiando el valor del atributo se cambia la clase
del elemento
● Por ejemplo, la clase del elemento h1 se cambia
modificando el atributo className

<h1 [class]="className">Title!</h1>

105
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Estilos
ejem5
● Activar una clase concreta con un atributo
boolean
● Activa o desactiva una clase red con el valor de
redActive
<h1 [class.red]="redActive">Title!</h1>

● Se puede usar para varias clases


<h1 [class.red]="redActive"
[class.yellow]="yellowActive">
Title!
</h1>
106
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Estilos
ejem5
● Asociar la clase de un elemento a un mapa
● Para gestionar varias clases es mejor usar un mapa
de string (nombre de la clase) a boolean (activa o
no)
<p [ngClass]="pClasses">Text</p>

pClasses = {
"red": false, changeParagraph(){
this.pClasses.bold = true;
"bold": true
}
}

107
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Estilos
ejem5
● Asociar un estilo concreto a un atributo
● En algunos casos es mejor cambiar el estilo
directamente en el elemento
<p [style.backgroundColor]="pColor">Text</p>

● Con unidades
<p [style.fontSize.em]="pSizeEm">Text</p>

<p [style.fontSize.%]="pSizePerc">Text</p>

108
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Estilos
ejem5
● Asociar un estilo concreto a un atributo
● Usando mapas de propiedad a valor

<p [ngStyle]="getStyles()">Text</p>

getStyles(){
return {
'font-style':this.canSave? 'italic':'normal',
'font-weight':!this.isUnchanged? 'bold':'normal',
'font-size':this.isSpecial? '24px':'8px',
}
}

109
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Formularios

● Existen diversas formas de controlar


formularios en Angular 2
● Vincular un control del formulario a un atributo del
componente (data binding)
● Acceso a los controles desde el código para leer y
modificar su estado
● Mecanismos avanzados con validación con
ngControl (no los veremos en el curso)

https://angular.io/docs/ts/latest/guide/forms.html
110
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Formularios
ejem6
● Campo de texto
● Se vincula el control a un atributo del componente
con [(ngModel)]
● Cualquier cambio en el control se refleja en el valor
del atributo (y viceversa)

<input type="text" [(ngModel)]="name">


<p>{{name}}</p>

name:string
111
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Formularios
ejem6
● Checkbox basado en booleanos
● Cada control se asocia con [(ngModel)] a un
atributo booleano y su valor depende de si está
“checked”
<input type="checkbox" [(ngModel)]="angular"/>
Angular
<input type="checkbox" [(ngModel)]="javascript"/>
JavaScript

angular:boolean
javascript:boolean
112
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Formularios
ejem6
● Checkbox basado en array de objetos
● Cada control se asocia con [(ngModel)] a un
atributo booleano de un objeto de un array
<span *ngFor="let item of items">
<input type="checkbox"
[(ngModel)]="item.selected"/> {{item.value}}
</span>

items = [
{value:'Item1', selected:false},
{value:'Item2',selected:false}
]
113
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Formularios
ejem6
● Botones de radio
● Todos los botones del mismo grupo se asocian al
mismo atributo con [(ngModel)]
● El valor del atributo es el “value” del control
<input type="radio" name="gender"
[(ngModel)]="gender" value="Male"> Male

<input type="radio " name="gender"


[(ngModel)]="gen der" value="Female"> Female

gender:string
114
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Formularios
ejem6
● Acceso a los controles desde el código
● Un elemento del template puede asociarse a una variable
● Podemos usar esa variable en el código del template para
manejar ese elemento
Este control input puede
referenciarse con la
variable cityInput
<input #cityInput type="text">

<button (click)="update(cityInput.value); cityInput.value=''">


Update city
</button>
Podemos la propiedades y métodos del
elemento definidos en su API DOM
115
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Formularios
ejem6

116
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Ejercicio 1

● Implementa una aplicación de gestión de tareas


● Las tareas se mantendrán en memoria

117
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Angular 2

● Introducción a Angular 2
● TypeScript
● Herramientas de desarrollo
● Componentes
● Templates
● Composición de componentes
● Cliente REST e inyección de dependencias
● Servicios
● Aplicaciones multipágina: Router
● Librerías de componentes
● Conclusiones
118
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes

Árboles de componentes
En Angular 2 un componente puede estar formado
por más componentes formando un árbol

App

Header Main Footer


*

Comp1 Comp2

119
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes

Árboles de componentes
En Angular 2 un componente puede estar formado
por más componentes formando un árbol

App

Header Main Footer


*

Comp1 Comp2

120
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
App
Árboles de componentes
Header

<header></header>
<p>Main content</p>
<h1>Title</h1>
<p>Main content</p> <header>
<h1>Title</h1>

121
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
App ejem7
Árboles de componentes
Header
app.component.ts header.component.ts
import {Component} from import {Component} from
'@angular/core'; '@angular/core';

@Component({ @Component({
selector: 'app-root', selector: 'header',
templateUrl: templateUrl:
'./app.component.html' './header.component.html'
}) })
export class AppComponent {}
export class HeaderComponent {}

app.component.html header.component.html
<header></header> <h1>Title</h1>
<p>Main content</p>
122
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
App ejem7
Árboles de componentes
Header
app.component.ts header.component.ts
import {Component} from import {Component} from
'@angular/core'; '@angular/core';

@Component({ @Component({
selector: 'app-root', selector: 'header',
templateUrl: templateUrl:
'./app.component.html' './header.component.html'
}) })
export class AppComponent {}
export class HeaderComponent {}

app.component.html header.component.html
Para incluir un
<header></header> componente se usa<h1>Title</h1>
<p>Main content</p> su selector
133
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
App ejem7
Árboles de componentes
Header
app.module.ts

import { BrowserModule } from '@angular/platform-browser';


import { FormsModule } from '@angular/forms';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';


import { HeaderComponent } from "./header.component";

@NgModule({
declarations: [AppComponent, HeaderComponent],
imports: [BrowserModule, FormsModule],
bootstrap: [AppComponent] Todos los
})
export class AppModule { }
componentes de
la app deben
declararse en el
@NgModule
124
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
ejem7
Árboles de componentes
● Al cargar la app en
el navegador, en el
árbol DOM cada
componente
incluye en su
elemento el
contenido de la
vista (HTML)
125
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes

● Comunicación entre un componente padre y


un componente hijo
● Configuración de propiedades (Padre →Hijo)
● Envío de eventos (Hijo →Padre)
● Invocación de métodos (Padre →Hijo)
● Con variable template

Inyectando hijo con @ViewChild


● Compartiendo el mismo servicio (Padre ↔Hijo)

https://angular.io/docs/ts/latest/cookbook/component-communication.html 126
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
ejem8
Configuración de propiedades
(Padre →Hijo)

● El componente padre puede especificar


propiedades en el componente hijo como si
fuera un elemento nativo HTML
El título de <header> será el valor del atributo appTitle
<header [title]='appTitle'></header>
<p>Main content</p>

https://angular.io/docs/ts/latest/cookbook/component-communication.html 127
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
ejem8
Configuración de propiedades
(Padre →Hijo)
app.component.ts header.component.ts
import {Component, Input} from
... '@angular/core';
...
export class AppComponent { export class HeaderComponent {
appTitle = 'Main Title';
} @Input()
private title: string;
}

app.component.html header.component.html
<header [title]='appTitle'></header> <h1>{{title}}</h1>
<p>Main content</p>

https://angular.io/docs/ts/latest/cookbook/component-communication.html 128
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
ejem8
Configuración de propiedades
(Padre →Hijo)
app.component.ts header.component.ts
import {Component, Input} from
... '@angular/core';
...
export class AppComponent { export class HeaderComponent {
appTitle = 'Main Title';
} @Input()
private title: string;
}

app.component.html header.c omponent.html

<header [title]='appTitle'></header> <h1>{{title}}</h1>


<p>Main content</p>

https://angular.io/docs/ts/latest/cookbook/component-communication.html 129
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
ejem8
Configuración de propiedades
(Padre →Hijo)
app.component.ts header.component.ts
import {Component, Input} from
... '@angular/core';
...
export class AppComponent { export class HeaderComponent {
appTitle = 'Main Title';
} @Input()
private title: string;
}

app.component.html header.component.html
<header [title]='appTitle'></header> <h1>{{title}}</h1>
<p>Main content</p>

https://angular.io/docs/ts/latest/cookbook/component-communication.html 130
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
ejem9
Envío de eventos
(Hijo →Padre)

● El componente hijo puede generar eventos


que son atendidos por el padre como si fuera
un elemento nativo HTML
La variable $event apunta al evento generado
<header (hidden)='hiddenTitle($event)'></header>
<p>Main content</p>

https://angular.io/docs/ts/latest/cookbook/component-communication.html 131
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
ejem9
Envío de eventos
(Hijo →Padre)
app.component.ts
...
export class AppComponent {
hiddenTitle(hidden: boolean){
console.log("Hidden:"+hidden)
}
}

app.component.html
<header (hidden)='hiddenTitle($event)'></header>
<p>Main content</p>

https://angular.io/docs/ts/latest/cookbook/component-communication.html 132
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
ejem9
Envío de eventos
(Hijo →Padre)
app.component.ts
...
export class AppComponent {
hiddenTitle(hidden: boolean){
console.log("Hidden:"+hidden)
}
}

app.component.html
<header (hidden)='hiddenTitle($event)'></header>
<p>Main content</p>

https://angular.io/docs/ts/latest/cookbook/component-communication.html 133
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
ejem9
Envío de eventos
(Hijo →Padre)
app.component.ts
...
export class AppComponent {
hiddenTitle(hidden: boolean){
console.log("Hidden:"+hidden) Los eventos pueden
} tener valores que se
} capturan con $event

app.component.html
<header (hidden)='hiddenTitle($event)'></header>
<p>Main content</p>

https://angular.io/docs/ts/latest/cookbook/component-communication.html 134
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
ejem9
Envío de eventos
(Hijo →Padre)
header.component.ts
import {Component, Output, EventEmitter} from '@angular/core';
...
export class HeaderComponent {

@Output()
hidden = new EventEmitter<boolean>();

visible = true;

click(){
this.visible = !this.visible;
this.hidden.next(this.visible);
}
}
header.component.html
<h1 *ngIf="visible">Title</h1>
<button (click)='click()'>Hide/Show</button>
135
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
ejem9
Envío de eventos
(Hijo →Padre)
header.component.ts
import {Component, Output, EventEmitter} from '@angular/core';
...
export class HeaderComponent {

@Output() Se declara un atributo de


hidden = new EventEmitter<boolean>(); tipo EventEmitter con la
anotación @Output
visible = true;
Para lanzar un evento se
click(){ invoca el método
this.visible = !this.visible; emit(valor)
this.hidden.emit(this.visible);
}
}
header.component.html
<h1 *ngIf="visible">Title</h1>
<button (click)='click()'>Hide/Show</button>
136
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes
ejem9
Envío de eventos
(Hijo →Padre)

137
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Ejercicio 2

● Refactoriza la aplicación de gestión de tareas para


que cada tarea sea un componente

138
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.
Composición de componentes

● ¿Cuándo crear un nuevo componente?


● El ejercicio y los ejemplos son excesivamente
sencillos para que compense la creación de un
nuevo componente hijo
● En casos reales se crearían nuevos componentes:
● Cuando la lógica y/o el template sean
suficientemente complejos
● Cuando los componentes hijos puedan
reutilizarse en varios contextos
139
Av. Arenales 395 Oficina 405 - 4336948 - info@cjavaperu.com CJava, siempre para apoyarte.

También podría gustarte