Download - Angular 2 Campus Madrid Septiembre 2016
![Page 3: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/3.jpg)
3
¿Quién soy?
developer
![Page 4: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/4.jpg)
4
¿Quién soy?
developer
![Page 5: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/5.jpg)
5
¿Quién soy?
developer
![Page 6: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/6.jpg)
6
¿Quién soy?
developer
![Page 7: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/7.jpg)
7
Consultoría y Formación enDesarrollo Software
Contacta con nosotros para cursos presenciales, online, in company
Micael [email protected]
@micael_gallegohttp://codeurjc.github.io
![Page 8: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/8.jpg)
8
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
![Page 9: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/9.jpg)
9
Introducción
● La última tendencia en el desarrollo web es la implementación de aplicaciones web SPA
● Las web SPA son clientes completos implementados con HTML, CSS y JavaScript que se comunican con el servidor web con API REST
● Existen frameworks especialmente diseñados para implementar webs SPA
● Uno de los frameworks más usados es Angular
● Acaba de publicarse la versión Angular 2
![Page 10: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/10.jpg)
10
Introducción
Frameworks / librerías SPA
![Page 11: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/11.jpg)
11
Introducción
Frameworks / librerías SPA
![Page 12: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/12.jpg)
12
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/
![Page 13: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/13.jpg)
13
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 para Angular 2
$scope
![Page 14: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/14.jpg)
14
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
![Page 15: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/15.jpg)
15
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
![Page 16: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/16.jpg)
16
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● ...
![Page 17: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/17.jpg)
17
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
![Page 18: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/18.jpg)
18
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
![Page 19: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/19.jpg)
19
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 y C#
![Page 20: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/20.jpg)
20
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 y TS, lo
que facilita migrar un proyecto existente
![Page 21: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/21.jpg)
21
TypeScript
export class Empleado {
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; }}
TypeScript
![Page 22: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/22.jpg)
22
TypeScript
Clases TypeScript vs JavaScript ES5
export class Empleado {
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; }}
Clase en TypeScript
function Empleado(nombre, salario){
this.nombre = nombre; this.salario = salario;}
Empleado.prototype.getNombre = function(){ return this.nombre;}; Empleado.prototype.toString = function(){ return "Nombre:"+this.nombre+", Salario:"+this.salario;};
Simulación de clase en JS ES5 con prototipos
![Page 23: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/23.jpg)
23
TypeScript
Clases Java vs TypeScript
public class Empleado { private String nombre; private double salario;
public Empleado(String nombre, double salario){ this.nombre = nombre; this.salario = salario; }
public String getNombre(){ return nombre; }
public String toString(){ return "Nombre:"+nombre+ ", Salario:"+salario; }}
Clase en Javaexport class Empleado {
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; }}
Clase en TypeScript
![Page 24: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/24.jpg)
24
TypeScript
Clases Java vs TypeScript
public class Empleado { private String nombre; private double salario;
public Empleado(String nombre, double salario){ this.nombre = nombre; this.salario = salario; }
public String getNombre(){ return nombre; }
public String toString(){ return "Nombre:"+nombre+ ", Salario:"+salario; }}
Clase en Javaexport class Empleado {
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; }}
Clase en TypeScript
En Java las clases son públicas. En TypeScript las clases se exportan
![Page 25: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/25.jpg)
25
TypeScript
Clases Java vs TypeScript
public class Empleado { private String nombre; private double salario;
public Empleado(String nombre, double salario){ this.nombre = nombre; this.salario = salario; }
public String getNombre(){ return nombre; }
public String toString(){ return "Nombre:"+nombre+ ", Salario:"+salario; }}
Clase en Javaexport class Empleado {
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; }}
Clase en TypeScript
En TS los tipos se ponen tras el nombre con : (dos puntos)
![Page 26: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/26.jpg)
26
TypeScript
Clases Java vs TypeScript
public class Empleado { private String nombre; private double salario;
public Empleado(String nombre, double salario){ this.nombre = nombre; this.salario = salario; }
public String getNombre(){ return nombre; }
public String toString(){ return "Nombre:"+nombre+ ", Salario:"+salario; }}
Clase en Javaexport class Empleado {
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; }}
Clase en TypeScript
En TS el constructor es “constructor”
![Page 27: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/27.jpg)
27
TypeScript
Clases Java vs TypeScript
public class Empleado { private String nombre; private double salario;
public Empleado(String nombre, double salario){ this.nombre = nombre; this.salario = salario; }
public String getNombre(){ return nombre; }
public String toString(){ return "Nombre:"+nombre+ ", Salario:"+salario; }}
Clase en Javaexport class Empleado {
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; }}
Clase en TypeScript
En TS los tipos se infieren (si quieres), incluso en el tipo que devuelven los métodos
![Page 28: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/28.jpg)
28
TypeScript
Clases Java vs TypeScript
public class Empleado { private String nombre; private double salario;
public Empleado(String nombre, double salario){ this.nombre = nombre; this.salario = salario; }
public String getNombre(){ return nombre; }
public String toString(){ return "Nombre:"+nombre+ ", Salario:"+salario; }}
Clase en Javaexport class Empleado {
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; }}
Clase en TypeScript
En TS siembre que quieras acceder a un elemento de la clase tendrás que usar this.
![Page 29: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/29.jpg)
29
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);});
TypeScript
![Page 30: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/30.jpg)
30
TypeScript
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
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);});
TypeScript
![Page 31: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/31.jpg)
31
TypeScript
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
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);});
TypeScript
En Java las clases de la misma carpeta son del mismo paquete. En TS cada fichero es un módulo, por eso hay que importar desde otros ficheros
![Page 32: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/32.jpg)
32
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
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);});
TypeScript
En TS 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
TypeScript
![Page 33: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/33.jpg)
33
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
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);});
TypeScript
TypeScript
En TS 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
![Page 34: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/34.jpg)
34
TypeScript
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
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);});
TypeScript
En Java usamos List y ArrayList generificados del API.En TS usamos el Array nativo de JS generificado por TS.
![Page 35: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/35.jpg)
35
TypeScript
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
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);});
TypeScript
En Java List el método es “add”En el array de JS el método es “push”
![Page 36: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/36.jpg)
36
TypeScript
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
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);});
TypeScript
La sintaxis del foreach es muy parecida en Java y TS. En TS está basado en iteradores (como en Java)
![Page 37: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/37.jpg)
37
TypeScript
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){ System.out.println(emp.getNombre());}
empleados.forEach(emp -> { System.out.println(emp);});
Java
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);});
TypeScript
Las expresiones lambda de Java se llaman arrow function en TS.Se diferencian en la “flecha” con – o con =
![Page 38: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/38.jpg)
38
Uso de this con la arrow function
function Empleado(nombre, sueldo){ this.nombre = nombre; this.sueldo = sueldo;}
Empleado.prototype.alerta(button){ var that = this; button.onclick = function(e){ alert(that.nombre); }}
En TypeScript una arrow function permite usar this y siempre apunta al objeto, no al evento (no es necesario usar that)
TypeScript
export class Empleado {
constructor( private nombre:string, private sueldo:number){}
alerta(button:HTMLButtonElement){ button.onclick = e => { alert(this.nombre); } }}
JavaScript TypeScript
![Page 39: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/39.jpg)
39
Lambdas / Arrow functions
int num = 0;
empleados.forEach(emp -> num++);
System.out.println(num);
Java
let num = 0;
empleados.forEach(emp => num++);
console.log(num);
TypeScript
En Java no se puede acceder a una variable que no sea final (declarada o efectiva) desde una lambda. En TS (como en JS) incluso se puede
cambiar el valor de la variable desde la propia arrow function
ERROR
TypeScript
![Page 40: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/40.jpg)
40
Uso de this con la arrow function
function Empleado(nombre, sueldo){ this.nombre = nombre; this.sueldo = sueldo;}
Empleado.prototype.alerta(button){ var that = this; button.onclick = function(e){ alert(that.nombre); }}
En TS 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)
export class Empleado {
private nombre:string, private sueldo:number){}
alerta(button:HTMLButtonElement){ button.onclick = e => { alert(this.nombre); } }}
JavaScript TypeScript
TypeScript
![Page 41: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/41.jpg)
41
Anotaciones
import {Component} from 'angular2/core';
@Component({selector: 'app',templateUrl: 'app.component.html'
})export class AppComponent { }
TypeScript
![Page 42: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/42.jpg)
42
Definición de atributos en el constructor
class Animal {
private name:string;
constructor(name: string) { this.name = name;
}}
TypeScript
![Page 43: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/43.jpg)
43
class Animal { constructor(private name: string) { }}
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 constructor declarando ese atributo como parámetro del constructor y usando el modificar de visibilidad
TypeScript
Definición de atributos en el constructor
![Page 44: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/44.jpg)
44
class Foo { get bar() { return ...; }
set bar(bar: boolean) { ... }}
Getter / Setter con sintaxis de atributo
let foo = new Foo();
if(foo.bar){ foo.bar = false;}
TypeScript
![Page 45: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/45.jpg)
45
class Foo { get bar() { return ...; }
set bar(bar: boolean) { ... }}
let foo = new Foo();
if(foo.bar){ foo.bar = false;}
TypeScript
Getter / Setter con sintaxis de atributo
![Page 46: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/46.jpg)
46
class Animal { eat() { } }class Dog extends Animal { woof() { } }class Cat extends Animal { meow() { } }
let pet: Animal = ...;if (pet instanceof Dog) { pet.woof();} else if (pet instanceof Cat) { pet.meow();} else { pet.eat();}
Type guards Instanceof / typeof
Disponible también en
Animal
eat()
Animal
eat()
Dog
woof()
Animal
eat()
Cat
meow()
TypeScript
![Page 47: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/47.jpg)
47
interface SquareConfig { color: string; width?: number;}
Objetos literales “tipados”
let config: SquareConfig;
config = {color: "black"};config = {color: "black", width: 20};
TypeScript
![Page 48: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/48.jpg)
48
interface SquareConfig { color: string; width?: number;}
Objetos literales “tipados”
let config: SquareConfig;
config = {color: "black"};config = {color: "black", width: 20};
TypeScript
![Page 49: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/49.jpg)
49
Programación asíncronaSimulación de sincronía con async / await
function loadData() { return getJSON('data.json') .then(data=>{
addHtmlToPage(data);
return data;
}).catch(err => { console.log(err) });}
async function loadData() { try {
let data = await getJSON('data.json');
addHtmlToPage(data); return data;
} catch(err){ console.log(err); } }
TypeScript
De momento sólo disponible cuando se genera código ES6 desde TS
![Page 50: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/50.jpg)
50
Programación asíncronaSimulación de sincronía con async / await
function loadData() { return getJSON('data.json') .then(data=>{
addHtmlToPage(data);
return data;
}).catch(err => { console.log(err) });}
async function loadData() { try {
let data = await getJSON('data.json');
addHtmlToPage(data); return data;
} catch(err){ console.log(err); } }
TypeScript
De momento sólo disponible cuando se genera código ES6 desde TS
![Page 51: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/51.jpg)
51
Tipos unión
let id: string | number;
id = 3;...Id = “3”;
if(typeof id === “string”){ ...}
En JS es habitual que ciertas variables puedan tener la misma
información aunque se represente con varios “tipos”.
TS permite definir variables con varios tipos
TypeScript
![Page 52: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/52.jpg)
52
Compatibilidad de tipos estructural
interface User { name: string;}
class Profile { constructor(public name:string){}}
let u: User;u = { name: "Pepe" };u = new Profile("Pepe");
TypeScript
![Page 53: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/53.jpg)
53
interface User { name: string;}
class Profile { constructor(public name:string){}}
let u: User;u = { name: "Pepe" };u = new Profile("Pepe");
Compatibilidad de tipos estructural
Un objeto Profile puede asignarse a una variable
de tipo User porque tiene un atributo name
TypeScript
![Page 54: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/54.jpg)
54
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){ console.log("p2"); } }}
Dos métodos con el mismo nombre deben tener una única
implementación que detecte cual ha sido llamado.
La implementación tiene que cubrir todas las cabeceras
TypeScript
![Page 55: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/55.jpg)
55
TypeScript
Editores / IDEsHay plugins para la mayoría de los editores / IDEs
Sublime Text Visual Studio Code WebStorm
![Page 56: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/56.jpg)
56
WebStorm 11
![Page 57: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/57.jpg)
57
WebStorm 11
![Page 58: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/58.jpg)
58
WebStorm 11
![Page 59: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/59.jpg)
59
Atom / atom-typescript
https://atom.io/packages/atom-typescript
![Page 60: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/60.jpg)
60
TypeScript
coffeescript
ES6
TypeScript
Popularidad de TypeScript
![Page 61: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/61.jpg)
61
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
![Page 62: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/62.jpg)
62
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
![Page 63: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/63.jpg)
63
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)
![Page 64: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/64.jpg)
64
Herramientas de desarrollo
Instalación node.js y npm● Para usar las herramientas de desarrollo de Angular 2 es
necesario instalar node.js 4 o superior● Instalación windows y mac
● Instalación linux
● Ubuntu
https://nodejs.org/en/download/stable/
https://nodejs.org/en/download/package-manager/
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -sudo apt-get install -y nodejssudo apt-get install -y nodejs-legacy
![Page 65: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/65.jpg)
65
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● Preprocesadores CSS● Optimización del código, CSS, HTML● Cumplimiento de estilos y generación de JavaScript
![Page 66: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/66.jpg)
66
Herramientas de desarrollo
Construcción de proyectos / empaquetado
http://broccolijs.com/
https://webpack.github.io/
http://gulpjs.com/
http://gruntjs.com/
![Page 67: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/67.jpg)
67
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
![Page 68: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/68.jpg)
68
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
![Page 69: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/69.jpg)
69
Herramientas de desarrollo
Generación de código esqueleto● Generadores de código Angular 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
![Page 70: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/70.jpg)
70
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
![Page 71: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/71.jpg)
71
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)
![Page 72: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/72.jpg)
72
Herramientas de desarrollo
● Herramienta oficial angular-cli● Instalación
● Pueden ser necesarios permisos de administrador
● Generación del proyecto● Se descargarán 250Mb de Internet y se configurarán las
herramientas. Puede tardar bastante tiempo.
npm install -g angular-cli
ng new ejem1cd ejem1
![Page 73: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/73.jpg)
73
Herramientas de desarrollo
● Herramienta oficial angular-cli
Construcción del proyecto
https://karma-runner.github.io
http://jasmine.github.io/
Herramientas de testing
http://www.protractortest.org/
https://webpack.github.io/
![Page 74: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/74.jpg)
74
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á a JavaScript
automáticamente
● En Windows es mejor ejecutar el comando como administrador para que vaya más rápido
ng serve
![Page 75: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/75.jpg)
75
Herramientas de desarrollo
![Page 76: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/76.jpg)
76
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
![Page 77: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/77.jpg)
77
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 compilador TS
![Page 78: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/78.jpg)
78
Herramientas de desarrollo
● Actualización del mensaje de la app
<h1> {{title}}</h1>
app.component.html
<h1> {{title}}</h1>
Hola caracola!
app.component.html
Al guardar un fichero el navegador se recarga de forma automática y vemos los cambios
![Page 79: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/79.jpg)
79
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
● 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
ng build
![Page 80: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/80.jpg)
80
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
![Page 81: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/81.jpg)
81
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
● Si compartimos el proyecto en git, la carpeta node_modules se ignora. Para regenerarla ejecutamos npm install después de clonar el proyecto.
npm install
![Page 82: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/82.jpg)
82
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
![Page 83: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/83.jpg)
83
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 clase TypeScript vinculada a la vista
![Page 84: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/84.jpg)
84
Componentes
Componentes en Angular 2● Copiamos el contenido de la carpeta src/app
del ejem1
![Page 85: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/85.jpg)
85
Componentes
Componentes en Angular 2ejem1
VistaLógica
app.component.html
<h1>My First Angular 2 App</h1>
import { Component } from '@angular/core';
@Component({ selector: 'app-root', templateUrl: './app.component.html'})export class AppComponent {}
app.component.ts
![Page 86: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/86.jpg)
86
app.component.html
<h1>My First Angular 2 App</h1>
import { Component } from '@angular/core';
@Component({ selector: 'app-root', templateUrl: './app.component.html'})export class AppComponent {}
Componentes
Componentes en Angular 2ejem1
VistaLógica
app.component.ts
![Page 87: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/87.jpg)
87
Componentes
Componentes en Angular 2
app.component.ts
app.component.html
ejem1
VistaLógica
<h1>My First Angular 2 App</h1>
import { Component } from '@angular/core';
@Component({ selector: 'app-root', templateUrl: './app.component.html'})export class AppComponent {}
Este componente no tiene ninguna lógica
![Page 88: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/88.jpg)
88
Componentes
<html><head>...</head><body> <app-root>Loading...</app-root></body></html>
src/index.html
ejem1app.component.ts
<h1>My First Angular 2 App</h1>
app.component.html
import { Component } from '@angular/core';
@Component({ selector: 'app-root', templateUrl: './app.component.html'})export class AppComponent {}
Para usar el componente se incluye en el index.html un
elemento HTML con el nombre indicado en el selector
(en este caso app-root)
![Page 89: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/89.jpg)
89
Componentes
ejem1
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({ declarations: [AppComponent], imports: [BrowserModule, FormsModule], bootstrap: [AppComponent]})export class AppModule { }
Componentes en Angular 2Toda app tiene un módulo que define los
componentes de la app, el componente principal y qué otros módulos necesita
Componentes declarados
Módulos importados
Componente principal
![Page 90: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/90.jpg)
90
Componentes
ejem1
index.ts
export * from './app.component';export * from './app.module';
Fichero que lista todos los ficheros TS de una carpeta
src/main.ts
import { AppModule } from './app/';
//...
Fichero índice de la carpetaEn TS 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
Al importar ese fichero se puede referenciar
cualquier clase de la carpeta (similar a
paquetes Java)
![Page 91: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/91.jpg)
91
Componentes
ejem1
![Page 92: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/92.jpg)
92
Componentes
Componentes en Angular 2
import { Component } from '@angular/core';
@Component({ selector: 'app-root', templateUrl: ` <h1> My First Angular 2 App </h1> `})export class AppComponent {}
app.component.ts
Se puede incluir la vista (HTML del template) directamente en
la clase. Si se usa la tildes invertidas ( `) (grave accent),se puede escribir HTML multilínea
ejem1
![Page 93: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/93.jpg)
93
Componentes
Visualización de una variableLa vista del componente (HTML) se genera en función
de su estado (atributos de la clase)
import { Component } from '@angular/core';
@Component({ selector: 'app-root', templateUrl: './app.component.html'})export class AppComponent { name = 'Anybody'; imgUrl = "assets/img.png";}
app.component.ts
<h1>Hello {{name}}!</h1><img [src]="imgUrl"/>
app.component.html
ejem2
![Page 94: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/94.jpg)
94
Componentes
Visualización de una variableLa vista del componente (HTML) se genera en función
de su estado (atributos de la clase)
import { Component } from '@angular/core';
@Component({ selector: 'app-root', templateUrl: './app.component.html'})export class AppComponent { name = 'Anybody'; imgUrl = "assets/img.png";}
app.component.ts
<h1>Hello {{name}}!</h1><img [src]="imgUrl"/>
app.component.html
ejem2
![Page 95: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/95.jpg)
95
Componentes
Recursos de la appLos recursos (imágenes, fonts..) deben colocarse en
una carpeta src/assets para que se copien en el build
ejem2
![Page 96: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/96.jpg)
96
Componentes
Ejecución de lógicaSe puede ejecutar un método ante un evento
producido en la vista del componente
import {Component} from '@angular/core';
@Component({ selector: 'app', templateUrl: './app.component.html'})export class AppComponent {
name = 'Anybody';
setName(name:string){ this.name = name; }}
app.component.ts
<h1>Hello {{name}}!</h1>
<button (click)="setName('John')"> Hello John</button>
app.component.html
ejem3
![Page 97: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/97.jpg)
97
Componentes
Ejecución de lógicaSe puede ejecutar un método ante un evento
producido en la vista del componente
import {Component} from '@angular/core';
@Component({ selector: 'app', templateUrl: './app.component.html'})export class AppComponent {
name = 'Anybody';
setName(name:string){ this.name = name; }}
app.component.ts
<h1>Hello {{name}}!</h1>
<button (click)="setName('John')"> Hello John</button>
app.component.html
ejem3
![Page 98: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/98.jpg)
98
Componentes
Ejecución de lógicaSe puede ejecutar un método ante un evento
producido en la vista del componente
import {Component} from '@angular/core';
@Component({ selector: 'app', templateUrl: './app.component.html'})export class AppComponent {
name = 'Anybody';
setName(name:string){ this.name = name; }}
app.component.ts
<h1>Hello {{name}}!</h1>
<button (click)="setName('John')"> Hello John</button>
app.component.html
ejem3
Se puede definir cualquier evento disponible en el
DOM para ese elemento
![Page 99: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/99.jpg)
99
Componentes
Ejecución de lógicaSe puede ejecutar un método ante un evento
producido en la vista del componente
ejem3
![Page 100: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/100.jpg)
100
import {Component} from '@angular/core';
@Component({ selector: 'app', templateUrl: './app.component.html'})export class AppComponent {
name = 'Anybody';
setName(name:string){ this.name = name; }}
app.component.ts
Componentes
Datos enlazados (data binding)Un campo de texto se puede “enlazar” a un atributo
Atributo y componente están sincronizados
<input type="text" [(ngModel)]="name">
<h1>Hello {{name}}!</h1>
<button (click)="setName('John')"> Hello John</button>
ejem4
app.component.html
![Page 101: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/101.jpg)
101
import {Component} from '@angular/core';
@Component({ selector: 'app', templateUrl: './app.component.html'})export class AppComponent {
name = 'Anybody';
setName(name:string){ this.name = name; }}
app.component.ts
Componentes
ejem4
<input type="text" [(ngModel)]="name">
<h1>Hello {{name}}!</h1>
<button (click)="setName('John')"> Hello John</button>
app.component.html
Datos enlazados (data binding)Un campo de texto se puede “enlazar” a un atributo
Atributo y componente están sincronizados
![Page 102: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/102.jpg)
102
Componentes
ejem4Datos enlazados (data binding)
Un campo de texto se puede “enlazar” a un atributoAtributo y componente están sincronizados
![Page 103: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/103.jpg)
103
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
![Page 104: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/104.jpg)
104
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
![Page 105: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/105.jpg)
105
Templates
● 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
● También se puede usar una expresión
<p *ngIf="visible">Text</p>
<p *ngIf="num == 3">Num 3</p>
ejem5
![Page 106: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/106.jpg)
106
Templates
● 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>
<div>Elem1</div><div>Elem2</div><div>Elem3</div>
items = [ { desc: 'Elem1', check: true }, { desc: 'Elem2', check: true }, { desc: 'Elem3', check: false }]
ejem5
![Page 107: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/107.jpg)
107
Templates
● 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
ejem5
![Page 108: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/108.jpg)
108
Templates
● Directivas● No se pueden incluir dos directivas estructurales (de tipo *) en
el mismo elemento
● 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)
ejem5
<template ngFor let-elem [ngForOf]="elems"> <li *ngIf="elem.check">{{elem.desc}}</li></template>
<li *ngFor="let elem of elems" *ngIf="elem.check"> {{elem.desc}}</li>
https://github.com/angular/angular/issues/4792
![Page 109: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/109.jpg)
109
Templates
● 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
ejem5
![Page 110: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/110.jpg)
110
Templates
● 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
ejem5
https://github.com/angular/angular-cli#global-styles
![Page 111: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/111.jpg)
111
Templates
● Estilos● En la propiedad styles o styleUrls de @Component
ejem5
@Component({selector: 'app-root',templateUrl: './app.component.html',styles: [`
.red { color: red; }
.blue { color: blue; }`]
})export class AppComponent { ...}
Se suelen usar los strings multilínea con tildes
invertidas
http://blog.thoughtram.io/angular/2015/06/25/styling-angular-2-components.html
![Page 112: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/112.jpg)
112
Templates
● Estilos● En la propiedad styles o styleUrls de @Component
ejem5
http://blog.thoughtram.io/angular/2015/06/25/styling-angular-2-components.html
@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
![Page 113: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/113.jpg)
113
Templates
● Estilos● En el template
ejem5
http://blog.thoughtram.io/angular/2015/06/25/styling-angular-2-components.html
<style> .orange { color: orange; }</style>
<h1 [class]="className">Hello {{name}}!</h1>
<button (click)="setClass('blue')">Blue</button>...
![Page 114: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/114.jpg)
114
Templates
● 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
ejem5
![Page 115: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/115.jpg)
115
Estilos
● 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>
ejem5
![Page 116: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/116.jpg)
116
Estilos
● Activar una clase concreta con un atributo boolean
● Activa o desactiva una clase red con el valor de redActive
● Se puede usar para varias clases
<h1 [class.red]="redActive">Title!</h1>
<h1 [class.red]="redActive" [class.yellow]="yellowActive"> Title!</h1>
ejem5
![Page 117: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/117.jpg)
117
Estilos
● 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, "bold": true}
changeParagraph(){ this.pClasses.bold = true;}
ejem5
![Page 118: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/118.jpg)
118
Estilos
● Asociar un estilo concreto a un atributo● En algunos casos es mejor cambiar el estilo
directamente en el elemento
● Con unidades
<p [style.backgroundColor]="pColor">Text</p>
<p [style.fontSize.em]="pSizeEm">Text</p>
<p [style.fontSize.%]="pSizePerc">Text</p>
ejem5
![Page 119: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/119.jpg)
119
Estilos
● 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', }}
ejem5
![Page 120: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/120.jpg)
120
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
![Page 121: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/121.jpg)
121
Formularios
● 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
ejem6
![Page 122: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/122.jpg)
122
Formularios
● 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:booleanjavascript:boolean
ejem6
![Page 123: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/123.jpg)
123
Formularios
● 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}
]
ejem6
![Page 124: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/124.jpg)
124
Formularios
● 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)]="gender" value="Female"> Female
gender:string
ejem6
![Page 125: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/125.jpg)
125
Formularios
● 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
ejem6
<input #cityInput type="text">
<button (click)="update(cityInput.value); cityInput.value=''"> Update city</button>
Este control input puede referenciarse con la
variable cityInput
Podemos la propiedades y métodos del elemento definidos en su API DOM
![Page 126: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/126.jpg)
126
Formularios
ejem6
![Page 127: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/127.jpg)
127
Ejercicio 1
● Implementa una aplicación de gestión de tareas
● Las tareas se mantendrán en memoria
![Page 128: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/128.jpg)
128
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
![Page 129: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/129.jpg)
129
Composición de componentes
Árboles de componentesEn Angular 2 un componente puede estar formado
por más componentes formando un árbol
App
Header FooterMain
Comp1 Comp2
*
![Page 130: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/130.jpg)
130
Composición de componentes
Árboles de componentesEn Angular 2 un componente puede estar formado
por más componentes formando un árbol
App
Header FooterMain
Comp1 Comp2
*
![Page 131: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/131.jpg)
131
Composición de componentes
Árboles de componentes
<header></header><p>Main content</p>
<h1>Title</h1>
App
Header
<h1>Title</h1><p>Main content</p> <header>
![Page 132: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/132.jpg)
132
Composición de componentes
Árboles de componentesApp
Header
import {Component} from '@angular/core';
@Component({ selector: 'app-root', templateUrl: './app.component.html'})export class AppComponent {}
app.component.ts
<header></header><p>Main content</p>
app.component.html
import {Component} from '@angular/core';
@Component({ selector: 'header', templateUrl: './header.component.html'})
export class HeaderComponent {}
header.component.ts
<h1>Title</h1>
header.component.html
ejem7
![Page 133: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/133.jpg)
133
Composición de componentes
Árboles de componentesApp
Header
import {Component} from '@angular/core';
@Component({ selector: 'app-root', templateUrl: './app.component.html'})export class AppComponent {}
app.component.ts
<header></header><p>Main content</p>
app.component.html
import {Component} from '@angular/core';
@Component({ selector: 'header', templateUrl: './header.component.html'})
export class HeaderComponent {}
header.component.ts
<h1>Title</h1>
header.component.html
ejem7
Para incluir un componente se usa
su selector
![Page 134: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/134.jpg)
134
Composición de componentes
Árboles de componentesApp
Header
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]})export class AppModule { }
app.module.ts
ejem7
Todos los componentes de
la app deben declararse en el
@NgModule
![Page 135: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/135.jpg)
135
Composición de componentes
Á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)
ejem7
![Page 136: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/136.jpg)
136
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
![Page 137: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/137.jpg)
137
Composición de componentes
Configuración de propiedades
● El componente padre puede especificar propiedades en el componente hijo como si fuera un elemento nativo HTML
ejem8
<header [title]='appTitle'></header><p>Main content</p>
https://angular.io/docs/ts/latest/cookbook/component-communication.html
(Padre Hijo)→
El título de <header> será el valor del atributo appTitle
![Page 138: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/138.jpg)
138
Composición de componentes
Configuración de propiedadesejem8
...
export class AppComponent { appTitle = 'Main Title';}
app.component.ts
<header [title]='appTitle'></header><p>Main content</p>
app.component.html
import {Component, Input} from '@angular/core';...export class HeaderComponent {
@Input() private title: string;}
header.component.ts
<h1>{{title}}</h1>
header.component.html
https://angular.io/docs/ts/latest/cookbook/component-communication.html
(Padre Hijo)→
![Page 139: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/139.jpg)
139
Composición de componentes
Configuración de propiedadesejem8
...
export class AppComponent { appTitle = 'Main Title';}
app.component.ts
<header [title]='appTitle'></header><p>Main content</p>
app.component.html
import {Component, Input} from '@angular/core';...export class HeaderComponent {
@Input() private title: string;}
header.component.ts
<h1>{{title}}</h1>
header.component.html
https://angular.io/docs/ts/latest/cookbook/component-communication.html
(Padre Hijo)→
![Page 140: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/140.jpg)
140
Composición de componentes
Configuración de propiedadesejem8
...
export class AppComponent { appTitle = 'Main Title';}
app.component.ts
<header [title]='appTitle'></header><p>Main content</p>
app.component.html
import {Component, Input} from '@angular/core';...export class HeaderComponent {
@Input() private title: string;}
header.component.ts
<h1>{{title}}</h1>
header.component.html
https://angular.io/docs/ts/latest/cookbook/component-communication.html
(Padre Hijo)→
![Page 141: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/141.jpg)
141
Composición de componentes
Envío de eventos
● El componente hijo puede generar eventos que son atendidos por el padre como si fuera un elemento nativo HTML
ejem9
<header (hidden)='hiddenTitle($event)'></header><p>Main content</p>
https://angular.io/docs/ts/latest/cookbook/component-communication.html
(Hijo Padre)→
La variable $event apunta al evento generado
![Page 142: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/142.jpg)
142
Composición de componentes
Envío de eventosejem9
https://angular.io/docs/ts/latest/cookbook/component-communication.html
(Hijo Padre)→
...export class AppComponent { hiddenTitle(hidden: boolean){ console.log("Hidden:"+hidden) }}
app.component.ts
<header (hidden)='hiddenTitle($event)'></header><p>Main content</p>
app.component.html
![Page 143: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/143.jpg)
143
Composición de componentes
Envío de eventosejem9
https://angular.io/docs/ts/latest/cookbook/component-communication.html
(Hijo Padre)→
...export class AppComponent { hiddenTitle(hidden: boolean){ console.log("Hidden:"+hidden) }}
app.component.ts
<header (hidden)='hiddenTitle($event)'></header><p>Main content</p>
app.component.html
![Page 144: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/144.jpg)
144
Composición de componentes
Envío de eventosejem9
https://angular.io/docs/ts/latest/cookbook/component-communication.html
(Hijo Padre)→
...export class AppComponent { hiddenTitle(hidden: boolean){ console.log("Hidden:"+hidden) }}
app.component.ts
<header (hidden)='hiddenTitle($event)'></header><p>Main content</p>
Los eventos pueden tener valores que se capturan con $event
app.component.html
![Page 145: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/145.jpg)
145
Composición de componentes
Envío de eventosejem9
(Hijo Padre)→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.ts
<h1 *ngIf="visible">Title</h1><button (click)='click()'>Hide/Show</button>
header.component.html
![Page 146: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/146.jpg)
146
Composición de componentes
Envío de eventosejem9
(Hijo Padre)→import {Component, Output, EventEmitter} from '@angular/core';...export class HeaderComponent {
@Output()hidden = new EventEmitter<boolean>();
visible = true;
click(){this.visible = !this.visible;this.hidden.emit(this.visible);
}}
header.component.ts
<h1 *ngIf="visible">Title</h1><button (click)='click()'>Hide/Show</button>
header.component.html
Se declara un atributo de tipo EventEmitter con la
anotación @Output
Para lanzar un evento se invoca el método
emit(valor)
![Page 147: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/147.jpg)
147
Composición de componentes
Envío de eventosejem9
(Hijo Padre)→
![Page 148: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/148.jpg)
148
Ejercicio 2
● Refactoriza la aplicación de gestión de tareas para que cada tarea sea un componente
![Page 149: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/149.jpg)
149
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
![Page 150: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/150.jpg)
150
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
![Page 151: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/151.jpg)
151
Cliente REST e inyección de dependencias
● Angular 2 dispone de su propio cliente de API REST● Es un objeto de la clase Http
https://angular.io/docs/ts/latest/guide/server-communication.html https://angular.io/docs/ts/latest/api/http/index/Http-class.html
Http http = ...
http.get(url).subscribe( response => console.log(response.json()), error => console.error(error));
![Page 152: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/152.jpg)
152
● Angular 2 dispone de su propio cliente de API REST● Es un objeto de la clase Http
Http http = ...
http.get(url).subscribe( response => console.log(response.json()), error => console.error(error));
El método subscribe recibe dos parámetros: 1) La función que se ejecutará cuando la petición sea correcta2) La función que se ejecutará cuando la petición sea errónea
Cliente REST e inyección de dependencias
https://angular.io/docs/ts/latest/guide/server-communication.html https://angular.io/docs/ts/latest/api/http/index/Http-class.html
![Page 153: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/153.jpg)
153
● Angular 2 dispone de su propio cliente de API REST● Es un objeto de la clase Http
Http http = ...
http.get(url).subscribe( response => console.log(response.json()), error => console.error(error));
Para obtener la respuesta del servidor usamos el método json()
del objeto response
Cliente REST e inyección de dependencias
https://angular.io/docs/ts/latest/guide/server-communication.html https://angular.io/docs/ts/latest/api/http/index/Http-class.html
![Page 154: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/154.jpg)
154
● ¿Cómo podemos acceder al objeto http?● Creando un objeto
● Podríamos crear un objeto nuevo cada vez que nos haga falta
● Esta opción dificulta hacer tests automáticos unitarios porque necesitaríamos que el servidor REST estuviese disponible y sería más difícil probar diferentes situaciones
Cliente REST e inyección de dependencias
![Page 155: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/155.jpg)
155
● ¿Cómo podemos acceder al objeto http?● Pidiendo al framework que proporcione el objeto
● Cuando la aplicación se ejecute, el objeto http sería un objeto real que hace peticiones al servidor REST
● Cuando ejecutemos los tests, el objeto http puede ser un sustituto (mock) que se comporte como queramos en el test pero no haga peticiones reales
Cliente REST e inyección de dependencias
![Page 156: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/156.jpg)
156
● Inyección de dependencias● La técnica que permite solicitar objetos al
framework se denomina inyección de dependencias
● Las dependencias que un módulo necesita son inyectadas por el sistema
● Esta técnica se ha hecho muy popular en el desarrollo de back-end en frameworks como Spring o Java EE
https://angular.io/docs/ts/latest/guide/dependency-injection.html
Cliente REST e inyección de dependencias
![Page 157: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/157.jpg)
157
● Para usar un objeto http tenemos que usar la inyección de dependencias
import { Component } from '@angular/core';import { Http } from '@angular/http';
@Component({ selector: 'app-root', templateUrl: './app.component.html'})export class AppComponent {
constructor(private http: Http) { }
search(title: string) { .... }}
Cliente REST e inyección de dependencias
![Page 158: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/158.jpg)
158
● Para usar un objeto http tenemos que usar la inyección de dependencias
import { Component } from '@angular/core';import { Http } from '@angular/http';
@Component({ selector: 'app-root', templateUrl: './app.component.html'})export class AppComponent {
constructor(private http: Http) { }
search(title: string) { .... }}
Cliente REST e inyección de dependencias
Definimos un parámetro Http en el constructor de
un componente
Cuando Angular construya el componente, inyectará
el objeto http solicitado
![Page 159: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/159.jpg)
159
● Para usar un objeto http tenemos que usar la inyección de dependencias
import { BrowserModule } from '@angular/platform-browser';import { FormsModule } from '@angular/forms';import { NgModule } from '@angular/core';import { HttpModule, JsonpModule } from '@angular/http';
import { AppComponent } from './app.component';
@NgModule({ declarations: [AppComponent], imports: [BrowserModule, FormsModule, HttpModule, JsonpModule], bootstrap: [AppComponent]})export class AppModule { }
Cliente REST e inyección de dependencias
![Page 160: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/160.jpg)
160
● Para usar un objeto http tenemos que usar la inyección de dependencias
import { BrowserModule } from '@angular/platform-browser';import { FormsModule } from '@angular/forms';import { NgModule } from '@angular/core';import { HttpModule, JsonpModule } from '@angular/http';
import { AppComponent } from './app.component';
@NgModule({ declarations: [AppComponent], imports: [BrowserModule, FormsModule, HttpModule, JsonpModule], bootstrap: [AppComponent]})export class AppModule { }
Cliente REST e inyección de dependencias
Ponemos una referencia a los módulos necesarios para REST:
HttpModule: Peticiones httpJsonpModule: Procesamiento
JSON
![Page 161: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/161.jpg)
161
● Ejemplo de buscador libros en Google Books
Cliente REST e inyección de dependencias
ejem10
![Page 162: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/162.jpg)
162
● Ejemplo de buscador libros en Google Booksejem10
<h1>Google Books</h1>
<input #title type="text">
<button (click)="search(title.value); title.value=''">Buscar</button>
<p *ngFor="let book of books">{{book}}</p>
app.component.html
Cliente REST e inyección de dependencias
![Page 163: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/163.jpg)
163
Cliente RESTimport {Component} from 'angular2/core';import {HTTP_PROVIDERS, Http} from 'angular2/http';
@Component({ selector: 'app', templateUrl: 'app/app.component.html', providers: [HTTP_PROVIDERS]})export class AppComponent {
private books: string[] = [];
constructor(private http: Http) {}
search(title: string) { this.books = []; let url = "https://www.googleapis.com/books/v1/volumes?q=intitle:"+title; this.http.get(url).subscribe( response => { let data = response.json(); for (var i = 0; i < data.items.length; i++) { let bookTitle = data.items[i].volumeInfo.title; this.books.push(bookTitle); } }, error => console.error(error) ); }}
ejem10app.component.ts
![Page 164: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/164.jpg)
164
Cliente RESTimport { Component } from '@angular/core';import { Http } from '@angular/http';
@Component({ selector: 'app-root', templateUrl: './app.component.html'})export class AppComponent {
private books: string[] = [];
constructor(private http: Http) { }
search(title: string) {
this.books = [];
let url = "https://www.googleapis.com/books/v1/volumes?q=intitle:"+title; this.http.get(url).subscribe( response => { let data = response.json(); for (var i = 0; i < data.items.length; i++) { let bookTitle = data.items[i].volumeInfo.title; this.books.push(bookTitle); } }, error => console.error(error) ); }}
ejem10app.component.ts
![Page 165: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/165.jpg)
165
● Peticiones POST
● Peticiones PUT
let data = { ... }this.http.post(url, data).subscribe( response => console.log(response), error => console.error(error));
Cliente REST e inyección de dependencias
let data = { ... }this.http.put(url, data).subscribe( response => console.log(response), error => console.error(error));
![Page 166: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/166.jpg)
166
Ejercicio 3
● Amplía el servicio de gestión de items para que utilice una API REST para gestionar los items
![Page 167: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/167.jpg)
167
Ejercicio 3
● Para ello se usará una aplicación web para el servidor (backend) que ofrece una API REST
● Es necesario Java 8 para que se pueda ejecutar● Se distribuye como un fichero .jar● Ejecución:
● La API REST se podrá usar cuando aparece
java -jar items-backend.jar
Tomcat started on port(s): 8080 (http)Started Application in 6.766 seconds (JVM running for 7.315)
![Page 168: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/168.jpg)
168
Ejercicio 3
● API REST Items● Creación de items
● Method: POST● URL: http://127.0.0.1:8080/items/● Headers: Content-Type: application/json● Body:
● Result:
● Status code: 201 (Created)
{ "description" : "Leche", "checked": false }
{ "id": 1, "description" : "Leche", "checked": false }
![Page 169: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/169.jpg)
169
Ejercicio 3
● API REST Items● Consulta de items
● Method: GET● URL: http://127.0.0.1:8080/items/● Result:
● Status code: 200 (OK)
[ { "id": 1, "description": "Leche", "checked": false }, { "id": 2, "description": "Pan", "checked": true }]
![Page 170: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/170.jpg)
170
Ejercicio 3
● API REST Items● Modificación de items
● Method: PUT● URL: http://127.0.0.1:8080/items/1● Headers: Content-Type: application/json● Body:
● Result:
● Status code: 200 (OK) / 404 (Not Found)
{ "id": 1, "description" : "Leche", "checked": true }
{ "id": 1, "description" : "Leche", "checked": true }
![Page 171: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/171.jpg)
171
Ejercicio 3
● API REST Items● Modificación de items
● Method: DELETE● URL: http://127.0.0.1:8080/items/1● Result:
● Status code: 200 (OK) / 404 (Not Found)
{ "id": 1, "description" : "Leche", "checked": true }
![Page 172: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/172.jpg)
172
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
![Page 173: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/173.jpg)
173
● Acoplar en el componente la lógica de las peticiones http no es una buena práctica
● El componente podría llegar a ser muy complejo y difícil de ampliar / modificar
● Es mucho más difícil implementar tests unitarios si el componente tiene muchas responsabilidades
● Es mucho mejor modularizar la aplicación en elementos que tengan una única responsabilidad
● Componente: Interfaz de usuario● Otro elemento: Peticiones http
Servicios
![Page 174: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/174.jpg)
174
● A los elementos de la aplicación que no se encargan del interfaz de usuario se les conoce como servicios
● Angular 2 ofrece muchos servicios predefinidos
● El objeto http se considera un servicio de acceso a APIs REST, pero existen más
● El desarrollador puede implementar sus propios servicios en la aplicación
● Para que sea más sencillo implementar tests, los servicios se inyectan en los componentes
Servicios
![Page 175: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/175.jpg)
175
● ¿Cómo se implementa un servicio?● Se crea una nueva clase para el servicio● Se anota esa clase con @Inyectable● Se indica esa clase en la lista de providers del
NgModule ● Se pone como parámetro en el constructor del
componente que usa el servicio
AppComponent BooksService
Servicios
![Page 176: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/176.jpg)
176
Servicios
Ejemplo de buscador de libros con información en memoria
ejem11
¿Cómo se implementa un servicio?
![Page 177: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/177.jpg)
177
¿Cómo se implementa un servicio?ejem11
Import { Injectable } from '@angular/core';
@Injectable()export class BooksService {
getBooks(title: string){ return [ 'Aprende Java en 2 días', 'Java para torpes', 'Java para expertos' ]; }}
books.service.ts
Servicios
![Page 178: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/178.jpg)
178
¿Cómo se implementa un servicio?ejem11
books.service.ts
Servicios
Import { Injectable } from '@angular/core';
@Injectable()export class BooksService {
getBooks(title: string){ return [ 'Aprende Java en 2 días', 'Java para torpes', 'Java para expertos' ]; }}
![Page 179: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/179.jpg)
179
¿Cómo se implementa un servicio?ejem11
import { Component } from '@angular/core';import { BooksService } from './books.service';
@Component({selector: 'app-root',templateUrl: './app.component.html'
})export class AppComponent {
private books: string[] = [];
constructor(private booksService: BooksService){}
search(title: string){ this.books = this.booksService.getBooks(title); }}
app.component.ts
Servicios
![Page 180: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/180.jpg)
180
¿Cómo se implementa un servicio?ejem11
app.component.ts
Servicios
import { Component } from '@angular/core';import { BooksService } from './books.service';
@Component({selector: 'app-root',templateUrl: './app.component.html'
})export class AppComponent {
private books: string[] = [];
constructor(private booksService: BooksService){}
search(title: string){ this.books = this.booksService.getBooks(title); }}
![Page 181: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/181.jpg)
181
¿Cómo se implementa un servicio?ejem11
app.module.ts
Servicios
import { BrowserModule } from '@angular/platform-browser';import { FormsModule } from '@angular/forms';import { NgModule } from '@angular/core';import { HttpModule, JsonpModule } from '@angular/http';
import { AppComponent } from './app.component';import { BooksService } from './books.service';
@NgModule({ declarations: [AppComponent], imports: [BrowserModule, FormsModule, HttpModule, JsonpModule], bootstrap: [AppComponent], providers: [BooksService]})export class AppModule { }
![Page 182: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/182.jpg)
182
¿Cómo se implementa un servicio?ejem11
app.module.ts
Servicios
import { BrowserModule } from '@angular/platform-browser';import { FormsModule } from '@angular/forms';import { NgModule } from '@angular/core';import { HttpModule, JsonpModule } from '@angular/http';
import { AppComponent } from './app.component';import { BooksService } from './books.service';
@NgModule({ declarations: [AppComponent], imports: [BrowserModule, FormsModule, HttpModule, JsonpModule], bootstrap: [AppComponent], providers: [BooksService]})export class AppModule { }
![Page 183: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/183.jpg)
183
Compartir servicios entre componentes● Es habitual que haya un único objeto de cada
servicio en la aplicación (singleton)● Es decir, todos los componentes comparten
“el mismo” servicio● De esa forma los servicios mantienen el
estado de la aplicación y los componentes ofrecen el interfaz de usuario
Servicios
![Page 184: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/184.jpg)
184
Compartir servicios entre componentes
AppComponent
BooksService
BookComponent
*
Servicios
![Page 185: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/185.jpg)
185
Servicio exclusivo para componente● Se puede hacer que servicio no sea compartido entre
todos los componentes de la aplicación (no sea singleton)
● Se puede crear un servicio exclusivo para un componente y sus hijos
● En vez de declarar el servicio en el atributo providers del @NgModule se declara en el @Component
● Puede ser compartido por el componente (padre) y por sus componentes hijos (incluidos en él)
Servicios
![Page 186: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/186.jpg)
186
import { Component } from '@angular/core';import { BooksService } from './books.service';
@Component({selector: 'app-root',templateUrl: './app.component.html',
providers: 'BooksService'})export class AppComponent {
constructor(private booksService: BooksService){}
...}
app.component.ts
Servicios
Servicio exclusivo para componente
![Page 187: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/187.jpg)
187
Servicios
Peticiones http en un servicio● No es buena práctica hacer peticiones http desde un
componente● Es mejor encapsular el acceso al backend con API
REST en un servicio● Ventajas
● Varios componentes pueden acceder al mismo backend compartiendo el mismo servicio (singleton)
● Es más fácil de testear● Es una buena práctica (más fácil de entender por otros
desarrolladores)
![Page 188: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/188.jpg)
188
Servicios
Peticiones http en un servicio● ¿Cómo se implementan los métodos de ese
servicio?● No pueden devolver información de forma
inmediata● Sólo pueden devolver información cuando llega la
respuesta del servidor● En JavaScript los métodos no se pueden bloquear
esperando la respuesta● Son asíncronos / reactivos
![Page 189: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/189.jpg)
189
Servicios
Peticiones http en un servicio● ¿Cómo se implementan los métodos de ese
servicio?
private service: BooksService = …
let books = this.booksService.getBooks(title);
console.log(books);
Un servicio que hace peticiones a una API REST NO PUEDE implementarse de forma
síncrona (bloqueante) en JavaScript
![Page 190: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/190.jpg)
190
Servicios
Peticiones http en un servicio● Existen principalmente 3 formas de
implementar un servicio con operaciones asíncronas en JavaScript
● Callbacks● Promesas● Observables
![Page 191: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/191.jpg)
191
Servicios
Peticiones http en un servicio● Callbacks: Se pasa como parámetro una función (de
callback) que será ejecutada cuando llegue el resultado. Esta función recibe como primer parámetro el error (si ha habido)
service.getBooks(title, (error, books) => { if(error){ return console.error(error); } console.log(books);});
![Page 192: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/192.jpg)
192
Servicios
Peticiones http en un servicio● Promesas: El método devuelve un objeto Promise.
Con el método then de ese objeto se define la función que se ejecutará cuando llegue el resultado. Con el método catch de ese objeto se define la función que se ejecutará si hay algún error
service.getBooks(title) .then(books => console.log(books)) .catch(error => console.error(error));
![Page 193: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/193.jpg)
193
Servicios
Peticiones http en un servicio● Observables: Similares a las promesas pero con
más funcionalidad. Con el método subscribe se definen las funciones que serán ejecutadas cuando llegue el resultado o si se produce un error
service.getBooks(title).subscribe( books => console.log(books), error => console.error(error));
![Page 194: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/194.jpg)
194
Servicios
Peticiones http en un servicio● Implementación de métodos asíncronos
● Callbacks: Hay muchas librerías implementadas así. Ya no se recomienda este enfoque porque es más limitado
● Promesas: La forma estándar en ES6. La forma recomendada si la funcionalidad es suficiente
● Observables: Implementados en la librería RxJS. Es la forma recomendada por Angular 2 por ser la más completa (aunque más compleja)
![Page 195: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/195.jpg)
195
Servicios
Servicio con Observables de RxJS
https://github.com/ReactiveX/RxJS
● RxJS: Extensiones reactivas para JavaScript
● La librería RxJS está incluida en Angular2● Es mucho más potente que las
promesas (estándar de ES6)● Nos vamos a centrar únicamente en los
aspectos que nos permitan implementar servicios con llamadas a una API REST
![Page 196: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/196.jpg)
196
Servicios
Servicio con Observables de RxJS● Tenemos que ofrecer objetos de alto nivel a los
clientes del servicio (p.e. array de titles)
● Pero al hacer una petición REST con http obtenemos un objeto Response
● El objetivo es transformar el objeto Response en array de titles cuando llegue la respuesta
service.getBooks(title).subscribe( books => console.log(books), error => console.error(error));
Objeto de alto nivel
ejem12
![Page 197: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/197.jpg)
197
Servicios
Servicio con Observables de RxJS
service.getBooks(title).subscribe( titles => console.log(titles), error => console.error(error));
...import 'rxjs/Rx';
export class BooksService { ... getBooks(title: string) { let url = ... return this.http.get(url).map( response => this.extractTitles(response) ) } private extractTitles(response: Response){...}}
Con el método map se indica la transformación
que hacemos a la respuesta para obtener el
objeto de alto nivel
El cliente del servicio accede al array de títulos
en vez de a la response
ejem12
![Page 198: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/198.jpg)
198
Servicios
Servicio con Observables de RxJS
service.getBooks(title).subscribe( titles => console.log(titles), error => console.error(error));
...import 'rxjs/Rx';
export class BooksService { ... getBooks(title: string) { let url = ... return this.http.get(url).map( response => this.extractTitles(response) ) } private extractTitles(response: Response){...}}
Para poder usar el método map es necesario importar
la librería rxjs/Rx
ejem12
![Page 199: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/199.jpg)
199
Servicios
import { Injectable } from '@angular/core';import { Http, Response } from '@angular/http';import 'rxjs/Rx';
@Injectable()export class BooksService {
constructor(private http: Http) { }
getBooks(title: string) {
let url = "https://www.googleapis.com/books/v1/volumes?q=intitle:"+ title;
return this.http.get(url).map( response => this.extractTitles(response) ) }
private extractTitles(response: Response) { return response.json().items.map( book => book.volumeInfo.title) }}
ejem12
books.service.ts
Método que extrae los títulos de la respuesta a
la API REST
![Page 200: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/200.jpg)
200
Servicios
import { Component } from '@angular/core';import { BooksService } from './books.service';
@Component({ selector: 'app-root', templateUrl: './app.component.html'})export class AppComponent {
private books: string[] = [];
constructor(private http: Http, private booksService: BooksService) {}
search(title: string) {
this.books = []; this.booksService.getBooks(title).subscribe( books => this.books = books, error => console.error(error) ); }}
ejem12app.component.ts
Cuando llega la respuesta se actualiza el array de books
![Page 201: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/201.jpg)
201
Servicios
Servicio con Observables de RxJS● Al igual que transformamos el resultado cuando la petición
es correcta, también podemos transformar el error para que sea de más alto nivel
● Usamos el método catch para gestionar el error. Podemos devolver un nuevo error o simular una respuesta correcta (con un valor por defecto)
getBooks(title: string) { let url = ... return this.http.get(url) .map(response => this.extractTitles(response)) .catch(error => Observable.throw('Server error'))}
Lanzamos un nuevo error
ejem13
![Page 202: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/202.jpg)
202
Cliente REST
Estado en los servicios http● Servicios stateless (sin estado)
● No guardan información● Sus métodos devuelven valores, pero no cambian el estado del
servicio● Ejemplo: BooksService con llamadas a Google
● Servicios statefull (con estado)● Mantienen estado, guardan información● Al ejecutar sus métodos cambian su estado interno, y también
pueden devolver valores● Ejemplo: BooksService con información en memoria
![Page 203: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/203.jpg)
203
Cliente REST
Estado en los servicios http● ¿Stateless vs statefull?
● Los servicios stateless son más fáciles de implementar porque básicamente encapsulan las peticiones REST al backend
● Pero la aplicación es menos eficiente porque cada vez que se visualiza un componente se tiene que pedir de nuevo la información
● Los servicios statefull son más complejos de implementar porque hay que definir una política de sincronización entre frontend y backend
● Pero la aplicación podría ser más eficiente porque no se consulta al backend constantemente
![Page 204: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/204.jpg)
204
Ejercicio 4
● Refactoriza el ejercicio 3 para que las llamadas a la API REST estén en un servicio stateless ItemsService
![Page 205: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/205.jpg)
205
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
![Page 206: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/206.jpg)
206
Aplicaciones multipágina: Router
● Las webs SPA (single page application) pueden tener varias pantallas simulando la navegación por diferentes páginas
https://angular.io/docs/ts/latest/guide/router.html
![Page 207: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/207.jpg)
207
Aplicaciones multipágina: Router
● El componente principal de la aplicación (app-root) tiene una parte fija (cabecera, footer) y una parte cuyo contenido depende de la URL (<router-outlet>)
● En app.routing.ts se define qué componente se muestra para cada URL
● Existen links especiales para navegar dentro de la aplicación web ([routerLink])
● Desde el código se puede navegar (Router)
https://angular.io/docs/ts/latest/guide/router.html
![Page 208: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/208.jpg)
208
Aplicaciones multipágina: Router
Componente principalejem14
import { Component } from '@angular/core';
@Component({ selector: 'app-root', template: ` <h1 class="title">Library</h1> <router-outlet></router-outlet> `})export class AppComponent { }
app.component.ts
![Page 209: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/209.jpg)
209
Aplicaciones multipágina: Router
Componente principalejem14
import { Component } from '@angular/core';
@Component({ selector: 'app-root', template: ` <h1 class="title">Library</h1> <router-outlet></router-outlet> `})export class AppComponent { }
app.component.ts
Zona que cambia en función de la URL
![Page 210: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/210.jpg)
210
Aplicaciones multipágina: Router
Configuración de las rutasejem14
import { Routes, RouterModule } from '@angular/router';
import { BookListComponent } from './book-list.component';import { BookDetailComponent } from './book-detail.component';
const appRoutes = [ { path: 'book/:id', component: BookDetailComponent, }, { path: 'books', component: BookListComponent }, { path: '', redirectTo: 'books', pathMatch: 'full' }]
export const routing = RouterModule.forRoot(appRoutes);
app.routing.ts
![Page 211: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/211.jpg)
211
Aplicaciones multipágina: Router
Configuración de las rutasejem14
import { Routes, RouterModule } from '@angular/router';
import { BookListComponent } from './book-list.component';import { BookDetailComponent } from './book-detail.component';
const appRoutes = [ { path: 'book/:id', component: BookDetailComponent, }, { path: 'books', component: BookListComponent }, { path: '', redirectTo: 'books', pathMatch: 'full' }]
export const routing = RouterModule.forRoot(appRoutes);
app.routing.ts
Para cada URL se indica un nombre y el componente
que será visualizado
![Page 212: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/212.jpg)
212
Aplicaciones multipágina: Router
Configuración de las rutasejem14
...import { routing } from './app.routing';
@NgModule({ declarations: [AppComponent, BookDetailComponent, BookListComponent], imports: [BrowserModule, FormsModule, HttpModule, JsonpModule, routing], bootstrap: [AppComponent], providers: [BookService]})export class AppModule { }
app.module.ts
![Page 213: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/213.jpg)
213
Aplicaciones multipágina: Router
Configuración de las rutasejem14
...import { routing } from './app.routing';
@NgModule({ declarations: [AppComponent, BookDetailComponent, BookListComponent], imports: [BrowserModule, FormsModule, HttpModule, JsonpModule, routing], bootstrap: [AppComponent], providers: [BookService]})export class AppModule { }
app.module.ts
Las rutas de consideran un módulo que debe importarse
en la aplicación
![Page 214: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/214.jpg)
214
Aplicaciones multipágina: Routerejem14
...@Component({ template: ` <h2>BOOKS</h2> <ul> <li *ngFor="let book of books"> <a [routerLink]="['/book',book.id]"> {{book.id}}-{{book.title}} </a> </li> </ul>`})export class BookListComponent {
books: Book[];
constructor(service: BookService) { this.books = service.getBooks(); }}
BookListComponentbook-list.component.ts
![Page 215: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/215.jpg)
215
Aplicaciones multipágina: Routerejem14
...@Component({ template: ` <h2>BOOKS</h2> <ul> <li *ngFor="let book of books"> <a [routerLink]="['/book',book.id]"> {{book.id}}-{{book.title}} </a> </li> </ul>`})export class BookListComponent {
books: Book[];
constructor(service: BookService) { this.books = service.getBooks(); }}
BookListComponentbook-list.component.ts
En vez de href, los links usan [routerLink]. La URL se puede
indicar como un string (completa) o como un array de
strings si hay parámetros
![Page 216: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/216.jpg)
216
Aplicaciones multipágina: Routerejem14
...import { Router, ActivatedRoute } from '@angular/router';
@Component({ template: `<h2>{{book.title}}</h2> <div><label>Id: </label>{{book.id}}</div> <div><label>Description: </label>{{book.description}}</div> <p><button (click)="gotoBooks()">Back</button></p>`})export class BookDetailComponent { book: Book;
constructor(private router: Router, activatedRoute: ActivatedRoute, service: BookService) { let id = activatedRoute.snapshot.params['id']; this.book = service.getBook(id); } gotoBooks() { this.router.navigate(['/books']); }}
BookDetailComponentbook-detail.component.ts
![Page 217: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/217.jpg)
217
Aplicaciones multipágina: Routerejem14
...import { Router, ActivatedRoute } from '@angular/router';
@Component({ template: `<h2>{{book.title}}</h2> <div><label>Id: </label>{{book.id}}</div> <div><label>Description: </label>{{book.description}}</div> <p><button (click)="gotoBooks()">Back</button></p>`})export class BookDetailComponent { book: Book;
constructor(private router: Router, activatedRoute: ActivatedRoute, service: BookService) { let id = activatedRoute.snapshot.params['id']; this.book = service.getBook(id); } gotoBooks() { this.router.navigate(['/books']); }}
BookDetailComponentbook-detail.component.ts
Para acceder a los parámetros desde el componente usamos el
servicio ActivatedRoute
![Page 218: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/218.jpg)
218
Aplicaciones multipágina: Routerejem14
...import { Router, ActivatedRoute } from '@angular/router';
@Component({ template: `<h2>{{book.title}}</h2> <div><label>Id: </label>{{book.id}}</div> <div><label>Description: </label>{{book.description}}</div> <p><button (click)="gotoBooks()">Back</button></p>`})export class BookDetailComponent { book: Book;
constructor(private router: Router, activatedRoute: ActivatedRoute, service: BookService) { let id = activatedRoute.snapshot.params['id']; this.book = service.getBook(id); } gotoBooks() { this.router.navigate(['/books']); }}
BookDetailComponentbook-detail.component.ts
Obtenemos un snapshot de los parámetros y accedemos al
parámetro id
![Page 219: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/219.jpg)
219
Aplicaciones multipágina: Routerejem14
...import { Router, ActivatedRoute } from '@angular/router';
@Component({ template: `<h2>{{book.title}}</h2> <div><label>Id: </label>{{book.id}}</div> <div><label>Description: </label>{{book.description}}</div> <p><button (click)="gotoBooks()">Back</button></p>`})export class BookDetailComponent { book: Book;
constructor(private router: Router, activatedRoute: ActivatedRoute, service: BookService) { let id = activatedRoute.snapshot.params['id']; this.book = service.getBook(id); } gotoBooks() { this.router.navigate(['/books']); }}
BookDetailComponentbook-detail.component.ts
Para navegar desde código usamos la dependencia Router y
el método navigate
![Page 220: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/220.jpg)
220
Aplicaciones multipágina: Router
● Funcionalidades avanzadas● Rutas para un componente concreto (no para toda la app)● Ejecutar código al salir de una pantalla
● Si el usuario navega a otra página “sin guardar” se le puede preguntar si realmente desea descartar los cambios o abortar la navegación
● Verificar si se puede ir a una nueva pantalla● Generalmente se comprueba si el usuario tiene permisos para
hacerlo● Carga perezosa de componentes (lazy loading)● Animaciones
https://angular.io/docs/ts/latest/guide/router.html
![Page 221: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/221.jpg)
221
Ejercicio 5
● Implementa una aplicación CRUD de gestión de libros
● Funcionalidades (varias pantallas)● Listado de todos los libros (títulos)● Formulario de nuevo libro● Vista de detalle de un libro● Modificación de libro● Borrado de un libro
● Se proporciona una API REST en Java 8 (similar a la de los items).
● Cada libro tiene las propiedades: id, title, description
![Page 222: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/222.jpg)
222
![Page 223: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/223.jpg)
223
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
![Page 224: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/224.jpg)
224
Librerías de componentes
● Angular 2 no proporciona componentes de alto nivel, usa HTML y CSS
● Se pueden usar cualquier librería de componentes que sólo tienen CSS: Bootstrap, Semantic ui, Google Material Design Lite...
http://www.getmdl.io/ http://getbootstrap.com/
http://semantic-ui.com/
![Page 225: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/225.jpg)
225
Librerías de componentes
● No se recomienda usar directamente librerías gráficas JavaScript con Angular 2:
● JQuery: Es mejor modificar el DOM con plantillas u otros mecanismos avanzados de Angular2
● JavaScript de Bootstrap: Está basado en jQuery. Es mejor usar ng2-bootstrap, componentes bootrstrap adaptados a Angular2
● Otras librerías: Es mejor usar aquellas con diseñadas para Angular 2 o con adaptadores para Angular2 para evitar problemas de rendimiento y en la construcción de la app
![Page 226: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/226.jpg)
226
Librerías de componentes
● ng2-bootstrap: Componentes de bootstrap reimplementados en Angular 2
http://valor-software.com/ng2-bootstrap/
![Page 227: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/227.jpg)
227
Librerías de componentes
● Material Design Angular 2: Librería de componentes
https://github.com/angular/material2 https://github.com/angular/material2
![Page 228: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/228.jpg)
228
Librerías de componentes
● ag-grid: Tabla con controles avanzados
https://www.ag-grid.com/
![Page 229: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/229.jpg)
229
Librerías de componentes
● SB Admin 2.0 ng2: Tema completo para admin
https://github.com/start-angular/SB-Admin-BS4-Angular-2
![Page 230: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/230.jpg)
230
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
![Page 231: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/231.jpg)
231
Conclusiones
● Introducción a Angular 2...● Un framework de desarrollo apps SPA● Se recomienda TypeScript, más preparado para grandes
aplicaciones (pero puede usar ES5, ES6 y Dart)● Orientado a componentes, con inyección de
dependencias y templates● No es compatible con Angular 1, pero comparte su filosofía● Mucho mejor rendimiento que Angular 1● Seguramente será uno de los frameworks más usados para
desarrollo web en los próximos años
![Page 232: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/232.jpg)
232
Conclusiones
● Angular 2 es mucho más..● Validación de formularios (con NgForm y NgControl)● Testing unitario y de integración (Jasmine, Karma,
Protractor, Inyección de dependencias de testing...)● Carga bajo demanda de componentes (para acelerar la
carga inicial de la aplicación)● Gestión del estado al estilo Redux (ngrx)● Animaciones
![Page 233: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/233.jpg)
233
Conclusiones
● Angular 2 es mucho más..● Aplicaciones con múltiples @NgModule (para
estructurar componentes y dependencias)● Optimización de la app en producción: Compilador de
templates a TS (angular-compiler), eliminación de funcionalidades de la librería no usadas… (tree shaking)
● Angular Universal: Renderizado en el servidor para optimizar la descarga inicial
![Page 234: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/234.jpg)
234
Conclusiones
● Ecosistema Angular● Angular2-electron: Aplicaciones de escritorio
multiplataforma con Angular2
● Ionic2: Aplicaciones móviles híbridas con Angular2
● NativeScript: Aplicaciones móviles con UI nativo con Angular2
● Angular2-Meteor: Framework JavaScript/TypeScript fullstack para desarrollo de apps web interactivas (comunicación websockets cliente servidor)
● AngularFire2: Cliente Angular 2 para el backend as a service Firebase de Google
![Page 235: Angular 2 Campus Madrid Septiembre 2016](https://reader030.vdocuments.co/reader030/viewer/2022032711/58716fcf1a28ab58758b7437/html5/thumbnails/235.jpg)
235
Curso de Angular 2 Avanzado
Enero 2017 / 20h / Presencial y Online
http://codeurjc.github.io