Introducción al framework Angular 2 para el desarrollo de aplicaciones Web. Revisión a sus conceptos principales y su alineación con el estándar Web Components.
Charla impartida el 26 de enero de 2017 para SevillaJS.
3. Prerrequisitos
NodeJS
https://nodejs.org
Editor de textos: tu editor favorito (con soporte a TS)
VS Code https://code.visualstudio.com
Atom https://atom.io
SublimeText 3 https://www.sublimetext.com/3
WebStorm https://www.jetbrains.com/webstorm/
Chrome Web Browser p.e. (cualquier evergreen browser nos sirve)
Git
4. Angular 2
Framework para capa cliente
Impulsado por Google
Diseñado para móvil primero, desktop después
AngularJS v. 1.0 tuvo una gran cuota de mercado. Ng2 reescrito desde
cero.
Abraza TypeScript como su principal lenguaje recomendado
6. Ng2 Breve Historia
Ng1 2009
Ng2 Alfa, Abril 2015
AtScript
TypeScript (acuerdo con Microsoft)
Entrada y Salida Rob Eisenberg @eisenbergEffect
Versiones rc.* (~)
Versión final 2.0 14 Septiembre, 2016
Versión actual 2.4.4
En preparación 4.x (Compatible con Ng2)
9. Organización de ficheros y carpetas
Nombrado de ficheros
PascalCase
camelCase
snake_case
kebab-case
Organización en carpetas por módulos y componentes
11. Angular-cli
Herramienta de línea de comando para agilizar la
creación de proyectos NG2
Generador de código sencillo semilla (scaffolding) tipo
Ruby On Rails
https://cli.angular.io
npm i –g angular-cli
12. Angular-cli
Creada por el equipo de NG2
Sigue las buenas practicas recomendadas por el
equipo
Referencia de comandos:
https://cli.angular.io/reference.pdf
14. ng-cli con preprocesadores de CSS
Soportados:
Sass/scss
Less
Stylus
https://github.com/angular/angular-cli#css-preprocessor-integration
ng new app0 --style=sass
15. Angular-cli. Comandos de generación
ng g component <nombre>
ng g directive <nombre>
ng g pipe <nombre>
ng g service <nombre>
ng g class <nombre>
ng g interface <nombre>
ng g enum <nombre>
ng g module <nombre>
Nuevo:
Componente
Directiva
Tubería
Servicio
Clase
Interfaz
Enumerado
Modulo
17. Módulos
Unidad lógica de organización de código en AngularJS2
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
imports: [ BrowserModule ],
providers: [ Logger ],
declarations: [ AppComponent ],
exports: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
18. Bootstraping
Punto de entrada y arranque
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
19. Librerías AngularJS2
Se instalan con npm
Se importan con import
import { Component } from ‘@angular/core';
20. Componentes
Clases que controlan el comportamiento, interacción con el usuario y
pintado de controles
@Component(…)
export class HeroListComponent implements OnInit {
heroes: Hero[];
selectedHero: Hero;
constructor(private service: HeroService) { }
ngOnInit() {
this.heroes = this.service.getHeroes();
}
selectHero(hero: Hero) { this.selectedHero = hero; }
}
21. Propiedades
Propiedades de un control visibles desde el exterior
export class UserComponent {
@Input() name: string;
@Input() surname: string;
}
<my-user name="Jesica" surname="Alba">
</my-user>
22. Eventos
Eventos públicos del componente
export class UserComponent {
@Output() selected = new EventEmitter();
…
this.selected.emit(params);
}
<my-user name="Jesica" (selected)="onSelected()">
</my-user>
23. Ciclo de vida del componente
Eventos que se disparan durante la inicialización y cierre de un
componente.
https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html
24. Plantillas
HTML con extensiones de plantillas para NG2
<h2>Hero List</h2>
<p><i>Pick a hero from the list</i></p>
<ul>
<li *ngFor="let h of heroes" (click)="selectHero(h)">
{{h.name}}
</li>
</ul>
<hero-detail *ngIf="selectedHero" [hero]="selectedHero">
</hero-detail>
25. Metadatos
Los metadatos son atributos (datos) que indican a NG2 como
procesar cada clase.
@Component({
moduleId: module.id,
selector: 'hero-list',
templateUrl: ‘./hero-list.component.html',
providers: [ HeroService ]
})
export class HeroListComponent implements OnInit {
/* . . . */
}
26. Enlace de datos
Hay tres modos de enlazar datos al DOM
One way [] o {{}}
Eventos ()
Two-way [()] Banana en la caja
<li>{{hero.name}}</li>
<hero-detail [hero]="selectedHero"></hero-
detail>
<li (click)="selectHero(hero)"></li>
<input [(ngModel)]="hero.name">
29. Directivas
Permiten extender el comportamiento de los componentes Angular a
nivel de estructural y de atributo.
Estructurales:
Atributo:
*ngFor *ngIf
<input [(ngModel)]="hero.name">
30. Servicios
Encapsulan comportamiento: calculo, comunicaciones (generalmente
sin interacción de UI) (lógica de negocio).
Se implementan con clases
export class Logger {
log(msg: any) { console.log(msg); }
error(msg: any) { console.error(msg); }
warn(msg: any) { console.warn(msg); }
}
export class HeroComponent {
constructor(private logger: Logger) { }
}
31. Inyección de Dependencias
Patrón de arquitectura que permite flexibilizar el reemplazo de
servicios en diferentes contextos (p.e. producción vs test)
@Injectable()
export class Logger {
log(msg: any) { console.log(msg); }
error(msg: any) { console.error(msg); }
warn(msg: any) { console.warn(msg); }
}
export class HeroComponent {
constructor(private logger: Logger) { }
}
32. Inyección de Dependencias
NG2 resuelve como inyectar dependencias usado la configuración de
proveedores.
providers: [ BackendService, HeroService, Logger ]
33. Inyección de Dependencias
El alcance de un servicio depende de donde se registra.
Se comportan como singleton (instancia única) a nivel de módulo o
componente raiz.
Se comportan como múltiples instancias si se registran a nivel de
componente (cada nuevo componente recibe una nueva copia
inyectada del servicio).
34. Sintaxis de plantillas
Interpolación
Calculo de cadenas en HTML y valores de atributos.
<p>My current hero is {{currentHero.firstName}}</p>
<h3>
{{title}}
<img src="{{heroImageUrl}}" style="height:30px">
</h3>
35. Expresiones en plantillas
Solo pueden referencias propiedades del componente.
Sin ámbito global. Sin acceso a window
Recomendaciones para expresiones:
Sin efectos secundarios (no side effects)
Ejecución rápida
Simplicidad
Idempotencia
<p>Longitud: {{2 * pi * radio}}</p>
36. Chuleta de trucos / Cheatsheet
Para tener a mano y actualizada:
https://angular.io/docs/ts/latest/guide/cheatsheet.html
37. Guía de Estilo NG2
Guía de estilo. Nombrado y estilo de código
https://angular.io/docs/ts/latest/guide/style-guide.html
38. Tuberías / Pipes
Una tubería permite formatear y filtrar datos.
Se pueden componer. En Ng1 se llamaban filtros.
Ejemplo de uso:
import { Component } from '@angular/core';
@Component({
selector: 'hero-birthday',
template: `<p>Born date: {{ d1 | date:shortDate }}</p>`
})
export class HeroBirthdayComponent {
d1 = new Date(1988, 3, 15); // April 15, 1988
}
39. Tuberías / Pipes
Ejemplo de implementación:
import { Pipe, PipeTransform } from '@angular/core';
/* Raise the value exponentially
* Takes an exponent argument that defaults to 1.
* Example: {{ 2 | exponentialStrength:10}} */
@Pipe({name: 'exponentialStrength'})
export class ExponentialStrengthPipe implements PipeTransform {
transform(value: number, exponent: string): number {
let exp = parseFloat(exponent);
return Math.pow(value, isNaN(exp) ? 1 : exp);
}
}
40. Tuberías / Pipes
Ejemplo de uso como filtro de una colección:
<div *ngFor="let hero of (heroes | flyingHeroes)">
{{hero.name}}
</div>
import { Pipe, PipeTransform } from '@angular/core';
import { Hero } from './heroes';
@Pipe({ name: 'flyingHeroes' })
export class FlyingHeroesPipe implements PipeTransform {
transform(allHeroes: Hero[]): Hero[] {
return allHeroes.filter(hero => hero.canFly);
}
}
41. Directivas Estructural *ngIf
Permite añadir contenido de forma condicional
<div *ngIf="condicion">
{{contenido}}
</div>
<div *ngIf="obj">
<p>{{obj.name}}</p>
</div>
42. Directivas Estructural *ngFor
Permite iterar una colección insertando contenido
para cada elemento
<div *ngFor=“let hero of heroes">
{{hero.name}} {{hero.lastname}}
</div>
43. Cliente HTTP
Nos permite salir del browser a la peligrosa Internet
Para usarlo tenemos que:
Importar el módulo HttpModule desde @angular/http
Importar las operaciones para Observables (dependencia)
import 'rxjs/operator';
44. Cliente HTTP. Ejemplo de uso en Servicio
Versión con Observables
import { Http, Headers, Response } from ‘@angular/http’;
…
constructor(private http: Http) {}
…
getCountries(): Observable<Country[]> {
return this.http.get(this.serviceUrl)
.map(this.extractData)
.catch(this.handleError);
}
45. Cliente HTTP. Ejemplo de uso en Servicio
Versión con Promesas
import { Http, Headers, Response } from ‘@angular/http’;
…
constructor(private http: Http) {}
…
getCountries (): Promise<Country[]> {
return this.http.get(this.serviceUrl)
.map(this.extractData)
.catch(this.handleError)
.toPromise();
46. Navegación / Router
¿Cómo navegar entre paginas?
El router proporciona mecanismo para navegar dentro de
la aplicación (SPA) reescribiendo la URL en el navegador
Es una de las piezas que mas cambios (roturas de
compatibilidad) ha tenido durante las betas y versiones RC
Ya está estabilizada, afortunadamente.
49. Navegación / Router
El Router es una tabla de rutas que mapea rutas a
componentes para resolver que componente debe
mostrarse al navegar a esa ruta.
El orden importa (precedencia de rutas) first-match-wins
No se pone ‘/’ al comienzo de ruta
‘’ = ruta por defecto
‘**’ = cualquier otra ruta
Se permiten parámetros en la ruta
50. Navegación / Router
Añadiendo la definición de rutas en el Module.ts
import { routing } from './app.routing';
…
@NgModule({
imports: [routing, …
52. Navegación / Router
Composición de rutas
Si la aplicación esta compuesta por diversos módulos,
cada modulo puede (y debe) gestionar sus rutas como
“sub-rutas”
Única diferencia, el registro:
export const routing = RouterModule.forRoot(routes);
export const citiesRoutes = RouterModule.forChild(routes);
53. WebComponents
La “moda”/estandar a punto de llegar
Recomendación de la W3C.
Polymer (impulsor)
Establece de modo estándar unas APIs mínimas para
permitir componentes en los navegadores.
Intro a Webcomponents.
https://component.kitchen/tutorial
54. WebComponents
Tecnologías subyacentes
1. Custom HTML Elements
2. HTML Templates
3. Shadow DOM DOM into DOM
4. HTML Imports
<link rel="import" href="my-element/my-element.html">
<my-tag> </my-tag>
<template>…
55. WebComponents
Con la popularalización de WebComponents
veremos:
Portales compuestos por componentes hechos con
diversas tecnologías como:
Polymer, AngularJS2, React, AngularJS1, Aurelia, jQuery,
…
Los componentes se comunican con el resto vía eventos y
propiedades (con o sin data-binding)