Beruflich Dokumente
Kultur Dokumente
Angular 2
Ionic 2
Micael Gallego
micael.gallego@urjc.es
@micael_gallego
https://github.com/micaelgallego/learn-ng2-ionic2
Consultora y Formacin en
Desarrollo Software
Contacta con nosotros para cursos
presenciales, online, in company
Micael Gallego
http://codeurjc.github.io
micael.gallego@urjc.es
@micael_gallego
2
SPA con
TypeScript y
Angular 2
Micael Gallego
micael.gallego@urjc.es
@micael_gallego
https://github.com/micaelgallego/learn-ng2-ionic2
Introduccin a Angular 2
TypeScript
Herramientas de desarrollo
Componentes
Templates
Composicin de componentes
Inyeccin de dependencias y servicios
Cliente REST
Aplicaciones multipgina: Router
Libreras de componentes
Conclusiones
Introduccin
Introduccin
Frameworks / libreras SPA
Introduccin
Frameworks / libreras SPA
Introduccin
Angular 2
Angular es un framework para desarrollo SPA
Permite extender el HTML con etiquetas propias
Introduccin
Angular 2 vs Angular 1
$scope
9
Introduccin
ES6
10
Introduccin
ES6
11
Introduccin
Funcionalidades de Angular 2
Inyeccin de dependencias
Servicios
Cliente http (APIs REST)
Navegacin por la app (Router)
Animaciones
Internacionalizacin
Soporte para tests unitarios y e2e
Libreras de componentes: Material Design
Renderizado en el servidor
...
12
Introduccin a Angular 2
TypeScript
Herramientas de desarrollo
Componentes
Templates
Composicin de componentes
Inyeccin de dependencias y servicios
Cliente REST
Aplicaciones multipgina: Router
Libreras de componentes
Conclusiones
13
TypeScript
Caractersticas
Aade tipos estticos a JavaScript ES6
Inferencia de tipos
Tipos opcionales
Anotaciones
http://www.typescriptlang.org/
https://www.gitbook.com/book/basarat/typescript/details
14
TypeScript
Ventajas frente a JavaScript
TypeScript
Facilidad de adopcin para JavaScripters
TypeScript
export class Empleado {
TypeScript
private nombre:string;
private salario:number;
constructor(nombre:string,salario:number){
this.nombre = nombre;
this.salario = salario;
}
getNombre(){
return this.nombre;
}
toString(){
return "Nombre:"+this.nombre+
", Salario:"+this.salario;
}
}
17
TypeScript
Clases TypeScript vs JavaScript ES5
Clase en TypeScript
18
TypeScript
Clases Java vs TypeScript
Clase en Java
public class Empleado {
Clase en 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;
}
}
19
TypeScript
Clases Java vs TypeScript
Clase en Java
public class Empleado {
Clase en 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;
}
}
20
TypeScript
Clases Java vs TypeScript
Clase en Java
public class Empleado {
Clase en 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;
}
}
21
TypeScript
Clases Java vs TypeScript
Clase en Java
public class Empleado {
Clase en 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;
}
}
22
TypeScript
Clases Java vs TypeScript
Clase en Java
public class Empleado {
Clase en 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;
}
}
23
TypeScript
Clases Java vs TypeScript
Clase en Java
public class Empleado {
Clase en 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;
}
}
24
TypeScript
TypeScript
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));
emps.push(new Empleado('Juan', 200));
for(let emp of emps){
console.log(emp.getNombre());
}
empleados.forEach(emp => {
console.log(emp);
});
25
TypeScript
Imports / Listas / foreach / lambdas
Java
TypeScript
import { Empleado } from "./Empleado";
empleados.forEach(emp -> {
System.out.println(emp);
});
empleados.forEach(emp => {
console.log(emp);
});
26
TypeScript
Imports / Listas / foreach / lambdas
Java
TypeScript
import { Empleado } from "./Empleado";
empleados.forEach(emp -> {
System.out.println(emp);
});
empleados.forEach(emp => {
console.log(emp);
});
En Java las clases del mismo paquete (carpeta) se pueden usar sin importar
En TypeScript se tienen que importar porque cada fichero es un mdulo diferente
27
TypeScript
Imports / Listas / foreach / lambdas
Java
TypeScript
import { Empleado } from "./Empleado";
empleados.forEach(emp -> {
System.out.println(emp);
});
empleados.forEach(emp => {
console.log(emp);
});
28
TypeScript
Imports / Listas / foreach / lambdas
Java
TypeScript
import { Empleado } from "./Empleado";
empleados.forEach(emp -> {
System.out.println(emp);
});
empleados.forEach(emp => {
console.log(emp);
});
29
TypeScript
Imports / Listas / foreach / lambdas
Java
TypeScript
import { Empleado } from "./Empleado";
empleados.forEach(emp -> {
System.out.println(emp);
});
empleados.forEach(emp => {
console.log(emp);
});
30
TypeScript
Imports / Listas / foreach / lambdas
Java
TypeScript
import { Empleado } from "./Empleado";
empleados.forEach(emp -> {
System.out.println(emp);
});
empleados.forEach(emp => {
console.log(emp);
});
31
TypeScript
Uso de this con la arrow function
JavaScript
function Empleado(nombre, sueldo){
this.nombre = nombre;
this.sueldo = sueldo;
}
Empleado.prototype.alerta(button){
var that = this;
button.onclick = function(e){
alert(that.nombre);
}
}
TypeScript
export class Empleado {
constructor(
private nombre:string,
private sueldo:number){}
alerta(button:HTMLButtonElement){
button.onclick = e => {
alert(this.nombre);
}
}
}
TypeScript
Objetos literales en TypeScript
interface SquareConfig {
color: string;
width?: number;
}
function createSquare(config: SquareConfig){
...
}
createSquare({color: "black"});
createSquare({color: "black", width: 20});
33
TypeScript
Objetos literales en TypeScript
interface SquareConfig {
color: string;
width?: number;
}
function createSquare(config: SquareConfig){
...
}
createSquare({color: "black"});
createSquare({color: "black", width: 20});
34
TypeScript
Atributos inicializados en el constructor
class Animal {
private name:string;
constructor(name: string) {
this.name = name;
}
}
class Animal {
constructor(private name: string) {
}
}
35
TypeScript
Atributos inicializados en el constructor
class Animal {
private name:string;
constructor(name: string) {
this.name = name;
}
}
class Animal {
constructor(private name: string) {
}
}
36
TypeScript
Instanceof sin casting
class Animal { eat() { } }
class Dog extends Animal { woof() { } }
class Cat extends Animal { meow() { } }
var pet: Animal = undefined;
if (pet instanceof Dog) {
pet.woof();
} else if (pet instanceof Cat) {
pet.meow();
} else {
pet.eat();
}
37
TypeScript
Instanceof sin casting
class Animal { eat() { } }
class Dog extends Animal { woof() { } }
class Cat extends Animal { meow() { } }
var pet: Animal = undefined;
if (pet instanceof Dog) {
pet.woof();
} else if (pet instanceof Cat) {
pet.meow();
} else {
pet.eat();
}
38
TypeScript
Compatibilidad de tipos estructural
interface User {
name: string;
}
class Profile {
constructor(public name:string){}
}
let u: User = { name: "Pepe" }
u = new Profile("Pepe");
39
TypeScript
Compatibilidad de tipos estructural
interface User {
name: string;
}
class Profile {
constructor(public name:string){}
}
let u: User = { name: "Pepe" }
u = new Profile("Pepe");
40
TypeScript
Editores / IDEs
Hay plugins para la mayora de los editores / IDEs
Sublime Text
Visual Studio
Code
WebStorm
41
TypeScript
Editores / IDEs
Hay plugins para la mayora de los editores / IDEs
Sublime Text
Visual Studio
Code
WebStorm
42
WebStorm 11
43
WebStorm 11
44
WebStorm 11
45
Atom / atom-typescript
https://atom.io/packages/atom-typescript
46
TypeScript
Popularidad de TypeScript
TypeScript
coffeescript
ES6
47
Introduccin a Angular 2
TypeScript
Herramientas de desarrollo
Componentes
Templates
Composicin de componentes
Inyeccin de dependencias y servicios
Cliente REST
Aplicaciones multipgina: Router
Libreras de componentes
Conclusiones
48
Herramientas de desarrollo
Herramientas de desarrollo
Plataforma y gestin de paquetes
Plataforma para
ejecutar aplicaciones JS
fuera del navegador
Gestor de herramientas
de desarrollo y libreras
JavaScript (integrado
con node.js)
50
Herramientas de desarrollo
Instalacin node.js y npm
Instalacin linux
https://nodejs.org/en/download/package-manager/
Ubuntu
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash sudo apt-get install -y nodejs
sudo apt-get install -y nodejs-legacy
51
Herramientas de desarrollo
Construccin de proyectos / empaquetado
Existen muchas herramientas para
procesar los fuentes de la aplicacin
Objetivos:
Herramientas de desarrollo
Construccin de proyectos / empaquetado
http://gulpjs.com/
http://gruntjs.com/
http://broccolijs.com/
https://webpack.github.io/
53
Herramientas de desarrollo
Generacin de cdigo esqueleto
Herramientas de desarrollo
Generacin de cdigo esqueleto
55
Herramientas de desarrollo
Generacin de cdigo esqueleto
56
Herramientas de desarrollo
Generacin de cdigo esqueleto
Generadores de cdigo 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 estn
actualizados a la ltima versin de Angular 2.
Pueden estar desactualizados
57
Herramientas de desarrollo
Generacin de cdigo 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 estn
actualizados a la ltima versin de Angular 2.
Pueden estar desactualizados
58
Herramientas de desarrollo
Generacin de cdigo esqueleto
Herramienta oficial de gestin de proyectos
https://github.com/angular/angular-cli
Ofrece comandos para:
Herramientas de desarrollo
Herramienta oficial angular-cli
Instalacin
60
Herramientas de desarrollo
http://jasmine.github.io/
http://broccolijs.com/
Construccin
del proyecto
http://www.protractortest.org/
Herramientas de testing
61
Herramientas de desarrollo
Herramienta oficial angular-cli
62
Herramientas de desarrollo
63
Herramientas de desarrollo
Ficheros/Carpetas generadas
64
Herramientas de desarrollo
Ficheros/Carpetas generadas
src/app:
65
Herramientas de desarrollo
main.html
<p>
main Works!
</p>
<router-outlet></router-outlet>
Al guardar un fichero el
navegador se recarga de
forma automtica y
vemos los cambios
main.html
<p>
Hola Caracola!
</p>
<router-outlet></router-outlet>
66
Herramientas de desarrollo
Herramienta oficial angular-cli
67
Herramientas de desarrollo
Edicin en Atom TypeScript
68
Herramientas de desarrollo
Optimizacin de espacio en disco
http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/
Introduccin a Angular 2
TypeScript
Herramientas de desarrollo
Componentes
Templates
Composicin de componentes
Inyeccin de dependencias y servicios
Cliente REST
Aplicaciones multipgina: Router
Libreras de componentes
Conclusiones
70
Componentes
Componentes en Angular 2
Componentes
Componentes en Angular 2
ejem1
app.component.ts
import {Component} from 'angular2/core';
@Component({
selector: 'app',
templateUrl: 'app/app.component.html'
})
export class AppComponent {
app.component.html
<h1>My First Angular 2 App</h1>
Lgica
Vista
72
Componentes
Componentes en Angular 2
ejem1
app.component.ts
import {Component} from 'angular2/core';
@Component({
selector: 'app',
templateUrl: 'app/app.component.html'
})
export class AppComponent {
app.component.html
<h1>My First Angular 2 App</h1>
Lgica
Vista
73
Componentes
Componentes en Angular 2
ejem1
app.component.ts
import {Component} from 'angular2/core';
@Component({
selector: 'app',
templateUrl: 'app.component.html'
})
export class AppComponent {
}
app.component.html
<h1>My First Angular 2 App</h1>
Este componente no
tiene ninguna lgica
Lgica
Vista
74
Componentes
ejem1
app.component.ts
import {Component} from 'angular2/core';
@Component({
selector: 'app',
templateUrl: 'app/app.component.html'
})
export class AppComponent {
app.component.html
<h1>My First Angular 2 App</h1>
index.html
<html>
<head>...</head>
<body>
<app>Loading...</app>
<!-- Scripts and libs -->
</body>
</html>
75
Componentes
ejem1
76
Componentes
Componentes en Angular 2
ejem1
app.component.ts
Componentes
Visualizacin de una variable
ejem2
app.component.html
<h1>Hello {{name}}!</h1>
<img [src]="imgUrl"/>
@Component({
selector: 'app',
templateUrl: 'app/app.component.html'
})
export class AppComponent {
name = 'Anybody';
imgUrl = "img.png";
}
78
Componentes
Visualizacin de una variable
ejem2
app.component.html
<h1>Hello {{name}}!</h1>
<img [src]="imgUrl"/>
@Component({
selector: 'app',
templateUrl: 'app/app.component.html'
})
export class AppComponent {
name = 'Anybody';
imgUrl = "img.png";
}
79
Componentes
Ejecucin de lgica
ejem3
80
Componentes
Ejecucin de lgica
ejem3
81
Componentes
ejem3
Ejecucin de lgica
Se puede ejecutar un mtodo ante un evento
producido en la vista del componente
app.component.ts
import {Component} from 'angular2/core';
@Component({
selector: 'app',
templateUrl: 'app/app.component.html'
})
export class AppComponent {
app.component.html
name = 'Anybody';
<h1>Hello {{name}}!</h1>
setName(name:string){
<button (click)="setName('John')">
this.name = name;
Hello John
}
</button>
}
82
Componentes
Ejecucin de lgica
ejem3
83
Componentes
Datos enlazados (data binding)
ejem4
app.component.html
@Component({
selector: 'app',
<input type="text" [(ngModel)]="name">
templateUrl: 'app/app.component.html'
})
<h1>Hello {{name}}!</h1>
export class AppComponent {
name = 'Anybody';
<button (click)="setName('John')">
Hello John
setName(name:string){
</button>
this.name = name;
}
84
Componentes
Datos enlazados (data binding)
ejem4
app.component.html
@Component({
selector: 'app',
<input type="text" [(ngModel)]="name">
templateUrl: 'app/app.component.html'
})
<h1>Hello {{name}}!</h1>
export class AppComponent {
name = 'Anybody';
<button (click)="setName('John')">
Hello John
setName(name:string){
</button>
this.name = name;
}
85
Componentes
Datos enlazados (data binding)
ejem4
86
Introduccin a Angular 2
TypeScript
Herramientas de desarrollo
Componentes
Templates
Composicin de componentes
Inyeccin de dependencias y servicios
Cliente REST
Aplicaciones multipgina: Router
Libreras de componentes
Conclusiones
87
Templates
Visualizacin condicional
Repeticin de elementos
Estilos
https://angular.io/docs/ts/latest/guide/template-syntax.html
88
Templates
Visualizacin condicional
ejem5
89
Templates
ejem5
Repeticin de elmentos
<div>Elem1</div>
<div>Elem2</div>
<div>Elem3</div>
90
Templates
Estilos
ejem5
91
Estilos
ejem5
Estilos
ejem5
* Hasta ahora hemos visto un nico componente en una pgina, pero veremos
cmo se pueden incluir ms
93
Estilos
ejem5
Atributo styles
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
styles: [`
.red { color: red; }
Se suelen usar los strings
.blue { color: blue; }
multilnea con tildes
`]
invertidas
})
export class AppComponent {
...
}
http://blog.thoughtram.io/angular/2015/06/25/styling-angular-2-components.html
94
Estilos
ejem5
Atributo styleUrls
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
styleUrls: ['app/app.component.css']
})
export class AppComponent {
...
}
http://blog.thoughtram.io/angular/2015/06/25/styling-angular-2-components.html
95
Estilos
ejem5
http://blog.thoughtram.io/angular/2015/06/25/styling-angular-2-components.html
96
Estilos
ejem5
<h1 [class.red]="redActive">Title!</h1>
<h1 [class.red]="redActive"
[class.yellow]="yellowActive">
Title!
</h1>
97
Estilos
Asociar la clase de un elemento a un mapa
ejem5
pClasses = {
"red": false,
"bold": true
}
changeParagraph(){
this.pClasses.bold = true;
}
98
Estilos
Asociar un estilo concreto a un atributo
ejem5
<p [style.backgroundColor]="pColor">Text</p>
Con unidades
<p [style.fontSize.em]="pSizeEm">Text</p>
<p [style.fontSize.%]="pSizePerc">Text</p>
99
Estilos
Asociar un estilo concreto a un atributo
ejem5
getStyles(){
return {
'font-style':this.canSave? 'italic':'normal',
'font-weight':!this.isUnchanged? 'bold':'normal',
'font-size':this.isSpecial? '24px':'8px',
}
}
100
Templates
101
Controles de formulario
Campo de texto
ejem6
name:string
102
Controles de formulario
ejem6
103
Controles de formulario
ejem6
Controles de formulario
Botones de radio
ejem6
gender:string
NOTA: En el momento de escribir este material(beta7) esta es la mejor forma de manipular
un grupo de botones de ratio. Es posible que se simplifique en versiones posteriores
105
Controles de formulario
ejem6
106
Ejercicio 1
107
Introduccin a Angular 2
TypeScript
Herramientas de desarrollo
Componentes
Templates
Composicin de componentes
Inyeccin de dependencias y servicios
Cliente REST
Aplicaciones multipgina: Router
Libreras de componentes
Conclusiones
108
Composicin de componentes
rboles de componentes
En Angular 2 un componente puede estar formado
por ms componentes formando un rbol
App
Header
Main
Footer
Comp1
Comp2
109
Composicin de componentes
rboles de componentes
En Angular 2 un componente puede estar formado
por ms componentes formando un rbol
App
Header
Main
Footer
Comp1
Comp2
110
Composicin de componentes
App
rboles de componentes
Header
<h1>Title</h1>
<p>Main content</p>
<header></header>
<p>Main content</p>
<header>
<h1>Title</h1>
111
Composicin de componentes
App
rboles de componentes
ejem7
Header
app.component.ts
header.component.ts
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
directives: [HeaderComponent]
})
export class AppComponent {}
@Component({
selector: 'header',
templateUrl:
'app/header.component.html'
})
export class HeaderComponent {}
app.component.html
header.component.html
<header></header>
<p>Main content</p>
<h1>Title</h1>
112
Composicin de componentes
App
rboles de componentes
ejem7
Header
app.component.ts
header.component.ts
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
directives: [HeaderComponent]
})
export class AppComponent {}
app.component.html
<header></header>
<p>Main content</p>
@Component({
selector: 'header',
templateUrl:
'app/header.component.html'
})
export class HeaderComponent {}
header.component.html
<h1>Title</h1>
113
Composicin de componentes
App
rboles de componentes
ejem7
Header
app.component.ts
header.component.ts
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
directives: [HeaderComponent]
})
export class AppComponent {}
app.component.html
En TypeScript es necesario importar
las clases de otro Mdulo (aunque
<header></header>
est en la misma carpeta
<p>Main content</p>
@Component({
selector: 'header',
templateUrl:
'app/header.component.html'
})
export class HeaderComponent {}
header.component.html
<h1>Title</h1>
114
Composicin de componentes
rboles de componentes
ejem7
Al cargar la app en
el navegador, en el
rbol DOM cada
componente
incluye en su
elemento el
contenido de la
vista (HTML)
115
Composicin de componentes
Comunicacin entre un componente padre y
un componente hijo
https://angular.io/docs/ts/latest/cookbook/component-communication.html
116
Composicin de componentes
Configuracin de propiedades
ejem8
(Padre Hijo)
117
Composicin de componentes
Configuracin de propiedades
ejem8
(Padre Hijo)
app.component.ts
...
export class AppComponent {
appTitle = 'Main Title';
}
header.component.ts
import {Component, Input} from
'angular2/core';
...
export class HeaderComponent {
@Input()
private title: string;
app.component.html
header.component.html
<header [title]='appTitle'></header>
<p>Main content</p>
<h1>{{title}}</h1>
https://angular.io/docs/ts/latest/cookbook/component-communication.html
118
Composicin de componentes
Configuracin de propiedades
ejem8
(Padre Hijo)
app.component.ts
...
export class AppComponent {
appTitle = 'Main Title';
}
header.component.ts
import {Component, Input} from
'angular2/core';
...
export class HeaderComponent {
@Input()
private title: string;
app.component.html
header.component.html
<header [title]='appTitle'></header>
<p>Main content</p>
<h1>{{title}}</h1>
https://angular.io/docs/ts/latest/cookbook/component-communication.html
119
Composicin de componentes
Configuracin de propiedades
ejem8
(Padre Hijo)
app.component.ts
...
export class AppComponent {
appTitle = 'Main Title';
}
header.component.ts
import {Component, Input} from
'angular2/core';
...
export class HeaderComponent {
@Input()
private title: string;
app.component.html
header.component.html
<header [title]='appTitle'></header>
<p>Main content</p>
<h1>{{title}}</h1>
https://angular.io/docs/ts/latest/cookbook/component-communication.html
120
Composicin de componentes
Envo de eventos
ejem9
(Hijo Padre)
<header (hidden)='hiddenTitle($event)'></header>
<p>Main content</p>
https://angular.io/docs/ts/latest/cookbook/component-communication.html
121
Composicin de componentes
Envo de eventos
ejem9
(Hijo Padre)
app.component.ts
...
export class AppComponent {
hiddenTitle(hidden: boolean){
console.log("Hidden:"+hidden)
}
}
<header (hidden)='hiddenTitle($event)'></header>
<p>Main content</p>
https://angular.io/docs/ts/latest/cookbook/component-communication.html
122
Composicin de componentes
Envo de eventos
ejem9
(Hijo Padre)
app.component.ts
...
export class AppComponent {
hiddenTitle(hidden: boolean){
console.log("Hidden:"+hidden)
}
}
app.component.html
<header (hidden)='hiddenTitle($event)'></header>
<p>Main content</p>
https://angular.io/docs/ts/latest/cookbook/component-communication.html
123
Composicin de componentes
Envo de eventos
ejem9
(Hijo Padre)
app.component.ts
...
export class AppComponent {
hiddenTitle(hidden: boolean){
console.log("Hidden:"+hidden)
}
}
<header (hidden)='hiddenTitle($event)'></header>
<p>Main content</p>
https://angular.io/docs/ts/latest/cookbook/component-communication.html
124
Composicin de componentes
Envo de eventos
header.component.ts
ejem9
(Hijo Padre)
click(){
this.visible = !this.visible;
this.hidden.next(this.visible);
}
header.component.html
<h1 *ngIf="visible">Title</h1>
<button (click)='click()'>Hide/Show</button>
125
Composicin de componentes
ejem9
Envo de eventos
header.component.ts
(Hijo Padre)
click(){
this.visible = !this.visible;
this.hidden.next(this.visible);
}
Se declara un atributo de
tipo EventEmitter con la
anotacin @Output
Para lanzar un evento se
invoca el mtodo
next(valor)
header.component.html
<h1 *ngIf="visible">Title</h1>
<button (click)='click()'>Hide/Show</button>
126
Ejercicio 2
127
Composicin de componentes
Cundo crear un nuevo componente?
Introduccin a Angular 2
TypeScript
Herramientas de desarrollo
Componentes
Templates
Composicin de componentes
Inyeccin de dependencias y servicios
Cliente REST
Aplicaciones multipgina: Router
Libreras de componentes
Conclusiones
129
https://angular.io/docs/ts/latest/guide/dependency-injection.html
130
ElemsService
131
ejem10
132
ejem10
app.component.html
<h1>Notes</h1>
<input #text type="text">
<button (click)="add(text.value); text.value =''">Add
</button>
<p *ngFor="#elem of elems">{{elem}}</p>
app.component.ts
...
export class AppComponent {
elems: string[] = []
add(elem: string){ this.elems.push(elem); }
}
133
ejem11
elems.service.ts
import {Injectable} from 'angular2/core';
@Injectable()
export class ElemsService {
public elems: string[] = []
add(elem: string){
this.elems.push(elem);
}
}
134
ejem11
elems.service.ts
import {Injectable} from 'angular2/core';
@Injectable()
export class ElemsService {
public elems: string[] = []
add(elem: string){
this.elems.push(elem);
}
}
135
ejem11
app.component.ts
import {Component} from 'angular2/core';
import {ElemsService} from './elems.service';
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
providers: [ElemsService]
})
export class AppComponent {
private elems: string[];
136
ejem11
app.component.ts
import {Component} from 'angular2/core';
import {ElemsService} from './elems.service';
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
providers: [ElemsService]
})
export class AppComponent {
private elems: string[];
137
ejem11
ElemsService
ElemComponent
140
ejem12
ejem12
elem.component.ts
142
ejem12
elem.component.ts
143
ejem12
app.component.ts
import {Component} from 'angular2/core';
import {ElemsService} from './elems.service';
import {ElemComponent} from './elem.component';
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
providers: [ElemsService],
directives: [ElemComponent]
})
export class AppComponent {
private elems: string[];
144
ejem12
app.component.ts
import {Component} from 'angular2/core';
import {ElemsService} from './elems.service';
import {ElemComponent} from './elem.component';
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
providers: [ElemsService],
directives: [ElemComponent]
})
export class AppComponent {
private elems: string[];
145
Ejercicio 3
146
Introduccin a Angular 2
TypeScript
Herramientas de desarrollo
Componentes
Templates
Composicin de componentes
Inyeccin de dependencias y servicios
Cliente REST
Aplicaciones multipgina: Router
Libreras de componentes
Conclusiones
147
Cliente REST
https://angular.io/docs/ts/latest/guide/server-communication.html
https://angular.io/docs/ts/latest/api/http/Http-class.html
148
Cliente REST
http.get(url).subscribe(
response => console.log(response.json()),
error => console.error(error)
);
https://angular.io/docs/ts/latest/guide/server-communication.html
https://angular.io/docs/ts/latest/api/http/Http-class.html
149
Cliente REST
http.get(url).subscribe(
response => console.log(response.json()),
error => console.error(error)
);
https://angular.io/docs/ts/latest/guide/server-communication.html
https://angular.io/docs/ts/latest/api/http/Http-class.html
150
Cliente REST
Cliente REST
HTTP_PROVIDERS es un
array con varios providers
(entre ellos Http)
Cliente REST
153
Cliente REST
ejem13
app.component.html
<h1>Google Books</h1>
<input #title type="text">
<button
(click)="search(title.value); title.value=''">
Buscar</button>
<p *ngFor="#book of books">{{book}}</p>
154
app.component.ts
Cliente REST
ejem13
@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)
);
}
155
Cliente REST
Peticiones POST
let data = ...
let url = ...
let body = JSON.stringify(data);
let headers = new Headers({
'Content-Type': 'application/json'
});
let options = new RequestOptions({headers});
this.http.post(url, body, options).subscribe(
response => console.log(response),
error => console.error(error)
);
156
Cliente REST
Peticiones http en un servicio
No es buena prctica hacer peticiones http desde un
componente
Es mejor encapsular el acceso al backend con API
REST en un servicio
Ventajas
157
Cliente REST
Peticiones http en un servicio
Cmo se implementan los mtodos de ese
servicio?
Cliente REST
Peticiones http en un servicio
Cliente REST
Peticiones http en un servicio
Existen principalmente 3 formas de
implementar un servicio con operaciones
asncronas en JavaScript
Callbacks
Promesas
Observables
160
Cliente REST
Peticiones http en un servicio
Cliente REST
Peticiones http en un servicio
Cliente REST
Peticiones http en un servicio
Cliente REST
Peticiones http en un servicio
Implementacin de mtodos asncronos
164
Cliente REST
Servicio con Observables de RxJS
165
Cliente REST
Servicio con Observables de RxJS
Objeto de
alto nivel
166
Cliente REST
Servicio con Observables de RxJS
...
import 'rxjs/Rx';
export class GoogleBooksService {
...
getBooks(title: string) {
let url = ...
return this.http.get(url).map(
response => this.extractTitles(response)
)
}
private extractTitles(response: Response){...}
}
service.getBooks(title).subscribe(
titles => console.log(titles),
error => console.error(error)
);
Cliente REST
Servicio con Observables de RxJS
...
import 'rxjs/Rx';
168
Cliente REST
googleservice.service.ts
ejem14
return this.http.get(url).map(
response => this.extractTitles(response)
)
169
Cliente REST
app.component.ts
ejem14
@Component({
selector: 'app',
templateUrl: 'app/app.component.html',
providers: [HTTP_PROVIDERS, GoogleBooksService]
})
export class AppComponent {
private books: string[] = [];
constructor(private http: Http, private service: GoogleBooksService) {}
search(title: string) {
this.books = [];
this.service.getBooks(title).subscribe(
books => this.books = books,
error => console.error(error)
);
Cliente REST
Servicio con Observables de RxJS
ejem15
getBooks(title: string) {
let url = ...
return this.http.get(url)
.map(response => this.extractTitles(response))
.catch(error => Observable.throw('Server error'))
}
171
Cliente REST
Estado en los servicios http
Servicios stateless (sin estado)
No guardan informacin
Sus mtodos devuelven valores, pero no cambian el estado del
servicio
Ejemplo: GoogleBooksService
Cliente REST
Estado en los servicios http
El componente es ms sencillo
El servicio se encarga de la gestin de datos y ofrece informacin de
alto nivel para que sea visualizada por el componente (estado de
carga, errores, etc)
173
Cliente REST
Estado en los servicios http
Existen muchas formas de implementar un servicio con
estado que se basa en una API REST
Cliente REST
Estado en los servicios http
Limitaciones de la estrategia bsica:
Ejercicio 4
176
Ejercicio 4
177
Ejercicio 4
API REST Items
Creacin de items
Method: POST
URL: http://127.0.0.1:8080/items/
Headers: Content-Type: application/json
Body:
{ "description" : "Leche", "checked": false }
Result:
{ "id": 1, "description" : "Leche", "checked": false }
Ejercicio 4
API REST Items
Consulta de items
Method: GET
URL: http://127.0.0.1:8080/items/
Result:
[
{ "id": 1, "description": "Leche", "checked": false },
{ "id": 2, "description": "Pan", "checked": true }
]
Ejercicio 4
API REST Items
Modificacin de items
Method: PUT
URL: http://127.0.0.1:8080/items/1
Headers: Content-Type: application/json
Body:
{ "id": 1, "description" : "Leche", "checked": true }
Result:
{ "id": 1, "description" : "Leche", "checked": true }
Ejercicio 4
API REST Items
Modificacin de items
Method: DELETE
URL: http://127.0.0.1:8080/items/1
Result:
{ "id": 1, "description" : "Leche", "checked": true }
181
Introduccin a Angular 2
TypeScript
Herramientas de desarrollo
Componentes
Templates
Composicin de componentes
Inyeccin de dependencias y servicios
Cliente REST
Aplicaciones multipgina: Router
Libreras de componentes
Conclusiones
182
https://angular.io/docs/ts/latest/guide/router.html
183
184
Componente principal
ejem16
...
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
@Component({
selector: 'app',
template: `
<h1 class="title">Component Router</h1>
<router-outlet></router-outlet>
`,
providers: [HeroService],
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
{path:'/heroes',name:'Heroes',component:HeroListComponent,useAsDefault:true},
{path:'/hero/:id',name:'HeroDetail',component: HeroDetailComponent},
])
export class AppComponent {}
185
Componente principal
ejem16
...
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
@Component({
selector: 'app',
template: `
<h1 class="title">Component Router</h1>
<router-outlet></router-outlet>
`,
providers: [HeroService],
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
{path:'/heroes',name:'Heroes',component:HeroListComponent,useAsDefault:true},
{path:'/hero/:id',name:'HeroDetail',component: HeroDetailComponent},
])
export class AppComponent {}
186
Componente principal
ejem16
...
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
@Component({
selector: 'app',
template: `
<h1 class="title">Component Router</h1>
<router-outlet></router-outlet>
`,
providers: [HeroService],
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
{path:'/heroes',name:'Heroes',component:HeroListComponent,useAsDefault:true},
{path:'/hero/:id',name:'HeroDetail',component: HeroDetailComponent},
])
export class AppComponent {}
187
Componente principal
ejem16
...
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
@Component({
selector: 'app',
template: `
<h1 class="title">Component Router</h1>
Hay rutas que pueden llevar
<router-outlet></router-outlet>
`,
parmetros (que podrn ser
providers: [HeroService],
ledos por el componente)
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
{path:'/heroes',name:'Heroes',component:HeroListComponent,useAsDefault:true},
{path:'/hero/:id',name:'HeroDetail',component: HeroDetailComponent},
])
export class AppComponent {}
188
Componente HeroList
ejem16
...
import {ROUTER_DIRECTIVES} from 'angular2/router';
@Component({
directives: [ROUTER_DIRECTIVES],
template: `
<h2>HEROES</h2>
<ul class="items">
<li *ngFor="#hero of heroes">
<a [routerLink]="['HeroDetail',{id:hero.id}]">
{{hero.id}} - {{hero.name}}</a>
</li>
</ul>`
})
export class HeroListComponent {
heroes: Hero[];
constructor(service: HeroService) {
this.heroes = service.getHeroes();
}
}
189
Componente HeroList
ejem16
...
En vez de href, los links usan
import {ROUTER_DIRECTIVES} from 'angular2/router';
[routerLink]. Se indica un array
@Component({
nombre y la segunda un objeto
directives: [ROUTER_DIRECTIVES],
con parmetros
template: `
<h2>HEROES</h2>
<ul class="items">
<li *ngFor="#hero of heroes">
<a [routerLink]="['HeroDetail',{id:hero.id}]">
{{hero.id}} - {{hero.name}}</a>
</li>
</ul>`
})
export class HeroListComponent {
heroes: Hero[];
constructor(service: HeroService) {
this.heroes = service.getHeroes();
}
}
190
Componente HeroDetail
ejem16
...
import {RouteParams, Router} from 'angular2/router';
@Component({
template: `
<h2>Hero {{hero.name}}</h2>
...
<button (click)="gotoHeroes()">Back</button>`
})
export class HeroDetailComponent {
hero: Hero;
constructor(private _router:Router,
routeParams:RouteParams, service: HeroService){
let id = routeParams.get('id');
this.hero = service.getHero(id);
}
gotoHeroes() {
this._router.navigate(['Heroes']);
}
}
191
Componente HeroDetail
ejem16
...
import {RouteParams, Router} from 'angular2/router';
@Component({
template: `
<h2>Hero {{hero.name}}</h2>
Para acceder a los parmetros
...
desde el componente usamos la
<button (click)="gotoHeroes()">Back</button>`
dependencia RouteParams
})
export class HeroDetailComponent {
hero: Hero;
constructor(private _router:Router,
routeParams:RouteParams, service: HeroService){
let id = routeParams.get('id');
this.hero = service.getHero(id);
}
gotoHeroes() {
this._router.navigate(['Heroes']);
}
}
192
Componente HeroDetail
ejem16
...
import {RouteParams, Router} from 'angular2/router';
@Component({
template: `
<h2>Hero {{hero.name}}</h2>
...
<button (click)="gotoHeroes()">Back</button>`
})
export class HeroDetailComponent {
Para navegar desde cdigo
hero: Hero;
usamos la dependencia Router y
constructor(private _router:Router,
el mtodo navigate
routeParams:RouteParams, service: HeroService){
let id = routeParams.get('id');
this.hero = service.getHero(id);
}
gotoHeroes() {
this._router.navigate(['Heroes']);
}
}
193
Redirecciones
Animaciones
https://angular.io/docs/ts/latest/guide/router.html
194
Introduccin a Angular 2
TypeScript
Herramientas de desarrollo
Componentes
Templates
Composicin de componentes
Inyeccin de dependencias y servicios
Cliente REST
Aplicaciones multipgina: Router
Libreras de componentes
Conclusiones
195
Libreras de componentes
http://semantic-ui.com/
http://getbootstrap.com/
http://www.getmdl.io/
196
Libreras de componentes
No se recomienda usar directamente libreras
grficas JavaScript con Angular 2:
[1] http://valor-software.com/ng2-bootstrap/
197
Libreras de componentes
https://github.com/angular/material2
198
Libreras de componentes
https://www.ag-grid.com/
199
Libreras de componentes
http://angularshowcase.github.io/ng2-bootstrap-sbadmin/
200
Introduccin a Angular 2
TypeScript
Herramientas de desarrollo
Componentes
Templates
Composicin de componentes
Inyeccin de dependencias y servicios
Cliente REST
Aplicaciones multipgina: Router
Libreras de componentes
Conclusiones
201
Conclusiones
Introduccin a Angular 2...
Conclusiones
Angular 2 es mucho ms..
Animaciones
203
Apps mviles
con Ionic 2
Micael Gallego
micael.gallego@urjc.es
@micael_gallego
https://github.com/micaelgallego/learn-ng2-ionic2
206
207
209
210
211
Ionic 2
Qu es?
http://ionicframework.com/
213
Ionic 2
Qu aporta ionic sobre apache cordova?
Ionic 2
215
Ionic 2
Herramientas y servicios
216
Ionic 2
Ionic-lab: App interactiva para prototipos
217
Ionic 2
Ionic-creator: Creacin interactiva de apps
218
Ionic 2
Ionic-view: Aplicacin mvil que permite visualizar
cualquier app ionic en desarrollo. Ideal para
ensear a clientes, probar en dispositivos...
219
Ionic 2
Ionic-platform: Servicios en la nube* para
facilitar el desarrollo de apps
* Servicios de pago
220
Instalacin de herramientas
Verificar instalacin
$ ionic
222
Creacin de proyecto
224
Creacin de proyecto
Creacin de proyecto
Mejor cambiar el
tamao del
browser para que
sea similar a un
mvil
Con ionic serve
podemos ver la
consola del
navegador en el
terminal
226
Creacin de proyecto
Estructura del proyecto
Configuracin
package.json: Libreras
typings.json: Libreras
tsconfig.json: Compilador
gulpfile.json: Construccin
Libreras descargadas
node_modules
typings
227
Creacin de proyecto
Estructura del proyecto
home.html: Plantilla
home.ts: Componente
home.scss: CSS
228
Pginas y componentes
Pginas vs Componentes
ejem1
app/pages/home/home.ts
230
Pginas y componentes
Librera de componentes
ejem1
231
Pginas y componentes
app/pages/home/home.html
ejem1
<ion-navbar *navbar>
<ion-title>
Home
</ion-title>
</ion-navbar>
<ion-content class="home">
<ion-card>
<ion-card-header>
Card Header
</ion-card-header>
<ion-card-content>
Hello World
</ion-card-content>
</ion-card>
</ion-content>
232
Pginas y componentes
Podemos usar:
Componentes personalizados
Http
No podemos usar:
Navegacin
Angular 2 vs ionic 2
235
Navegacin
Ionic 2
@Page({
template: `
<ion-navbar *navbar><ion-title>Login</ion-title></ion-navbar>
<ion-content>
<button (click)="goToOtherPage()">Go to OtherPage</button>
</ion-content>`
})
export class StartPage {
constructor(private nav: NavController){}
goToOtherPage(){ nav.push(OtherPage); }
}
236
Navegacin
Ionic 2
237
Navegacin
ejem2
238
Navegacin
app/pages/home/home.ts
ejem2
239
Navegacin
ejem2
app/pages/home/home.html
<ion-navbar *navbar>
<ion-title>Home</ion-title>
</ion-navbar>
<ion-content>
<ion-card *ngFor="#elem of elems"
(click)="goToDetails(elem)">
<ion-card-header>
{{ elem.name }}
</ion-card-header>
</ion-card>
</ion-content>
240
Navegacin
ejem2
app/pages/details/details.ts
Navegacin
ejem2
app/pages/details/details.html
<ion-navbar *navbar>
<ion-title>
{{ elem.name }}
</ion-title>
</ion-navbar>
<ion-content>
{{ elem.desc }}
</ion-content>
242
GitHub app
ejem3
http://gonehybrid.com/build-your-first-mobile-app-with-ionic-2-angular-2/
244
GitHub app
Arquitectura de la app
ejem3
HomePage
GitHubService
DetailsPage
245
app/pages/home/home.ts
GitHub app
ejem3
246
GitHub app
ejem3
app/pages/home/home.html
<ion-content class="home">
<ion-list inset>
<ion-item>
<ion-label>Username</ion-label>
<ion-input [(ngModel)]="username" type="text">
</ion-input>
</ion-item>
</ion-list>
<div padding>
<button block (click)="getRepos()">Search</button>
</div>
<ion-card *ngFor="#repo of foundRepos" (click)="goToDetails(repo)">
<ion-card-header>
{{ repo.name }}
</ion-card-header>
<ion-card-content>
{{ repo.description }}
</ion-card-content>
</ion-card>
</ion-content>
247
GitHub app
app/pages/details/details.html
ejem3
248
GitHub app
ejem3
app/pages/details/details.html
<ion-navbar *navbar>
<ion-title>
{{ repo.name }}
</ion-title>
</ion-navbar>
<ion-content>
<div padding [innerHTML]="readme"></div>
</ion-content>
249
GitHub
app
import {Injectable} from 'angular2/core';
ejem3
app/services/github.ts
252
Subimos la app
$ ionic upload
254
Conclusiones
Consultora y Formacin en
Desarrollo Software
Contacta con nosotros para cursos
presenciales, online, in company
Micael Gallego
http://codeurjc.github.io
micael.gallego@urjc.es
@micael_gallego
257