Manual De Angular Angular7

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 141

DownloadManual De Angular Angular7
Open PDF In BrowserView PDF
INDRA OPEN UNIVERSITY
PRESENTACION DEL CURSO

1

ESCUELA:
TECNOLOGÍA

ANGULAR 2+

13

1

ÍNDICE

▪ Introducción a TypeScript
▪ Introducción a Angular 2+
▪ Herramientas de Desarrollo
▪ Módulos
▪ Plantillas
▪ Formularios
▪ Servicios
▪ Acceso al servidor
▪ Enrutamiento y navegación

Título del documento

| 15

15

ESCUELA:
TECNOLOGÍA

ANGULAR 2.0

▪

NOMBRE APELLIDO PROFESOR
Javier Martín

▪

VER PERFIL COMPLETO:

▪

CONTACTO

jmartin@grupoloyal.com

Título del documento

| 16

16

2

Angular 7
https://angular.io/

© JMA 2016. All rights reserved

20

Contenidos
•

Introducción a TypeScript
–
–
–
–

•

Introducción a Angular 2
–
–
–
–
–

•

•

•

Instalación de utilidades
Creación de una aplicación
Estructura de la aplicación
Librerías de terceros
Metadata
Módulo principal
Módulos de características
Módulos Angular 2 vs JavaScript

–
–
–
–

Clases como servicios
Dependency injection
Proveedores
Inyectores

•

Vinculación bidireccional
Validaciones
Estilos visuales

Acceso al servidor
–
–
–
–

Servicios

Data binding
Marcadores
Directivas
Transformaciones (Pipes)

Formularios
–
–
–

•

Selectores especiales
Encapsulación
Preprocesadores CSS

Plantillas
–
–
–
–

•

Plantillas y estilos
Propiedades de entrada
Eventos de salida
Ciclo de vida

Estilos
–
–
–

Módulos
–
–
–
–

•

Características
Angulas JS vs Angular 2
Arquitectura
Elementos estructurales
Model View ViewModel (MVVM)

Componentes
–
–
–
–

Herramientas de Desarrollo
–
–
–
–

•

•

Sistema de tipos
Sintaxis ampliada
Clases, herencia, genéricos e interfeces
Módulos y decoradores

Patrón Observable (RxJS).
HttpModule y JsonpModule
Servicios RESTFul
JSONP

Enrutamiento y navegación
–
–
–
–

RouterModule
Definición de rutas
Paso de parámetros
Navegación

© JMA 2016. All rights reserved

21

3

INTRODUCCIÓN A ANGULAR 2+

© JMA 2016. All rights reserved

22

Arquitectura Web
• Una aplicación Web típica recogerá datos del usuario
(primer nivel), los enviará al servidor, que ejecutará un
programa (segundo y tercer nivel) y cuyo resultado
será formateado y presentado al usuario en el
navegador (primer nivel otra vez).

© JMA 2016. All rights reserved

23

4

Single-page application (SPA)
• Un single-page application (SPA), o aplicación de página única es
una aplicación web o es un sitio web que utiliza una sola página con
el propósito de dar una experiencia más fluida a los usuarios como
una aplicación de escritorio.
• En un SPA todo el códigos de HTML, JavaScript y CSS se carga de
una sola vez o los recursos necesarios se cargan dinámicamente
cuando lo requiera la página y se van agregando, normalmente
como respuesta de los acciones del usuario.
• La página no se tiene que cargar otra vez en ningún punto del
proceso, tampoco se transfiere a otra página, aunque las
tecnologías modernas (como el pushState() API del HTML5) pueden
permitir la navegabilidad en páginas lógicas dentro de la aplicación.
• La interacción con las aplicaciones de página única pueden
involucrar comunicaciones dinámicas con el servidor web que está
por detrás, habitualmente utilizando AJAX o WebSocket (HTML5).
© JMA 2016. All rights reserved

24

Introducción
•
•
•

•
•
•

•

Angular (comúnmente llamado "Angular 2+" o "Angular 2") es un framework
estructural para aplicaciones web de una sola página (SPA) siguiendo el patrón
MVVM y orientación a componentes.
Permite utilizar el HTML como lenguaje de plantillas y extender la sintaxis del
HTML para expresar los componentes de la aplicación de forma declarativa, clara y
sucinta .
El enlazado de datos y la inyección de dependencias eliminan gran parte del
código que de otra forma se tendría que escribir. Y todo sucede dentro del
navegador, lo que lo convierte en un buen socio para cualquier tecnología de
servidor.
Angular es un framework que pretende definir la arquitectura de la aplicación.
Define claramente la separación entre el modelo de datos, el código, la
presentación y la estética.
Estás obligado por Angular a seguir esa estructura. Ya no haces el JavaScript como
tu quieres sino como Angular te manda. Y eso realmente da mucha potencia a la
aplicación ya que, al seguir una arquitectura definida, Angular puede ayudarte en
la aplicación y a tener todo mucho mas estructurado.
Angular es la evolución de AngularJS aunque incompatible con su predecesor.

© JMA 2016. All rights reserved

25

5

Novedades
•

En AngularJS la escalabilidad estaba limitada por:
– Lenguaje JavaScript
– Precarga del código.

•
•
•
•
•
•

•
•
•

Uso de TypeScript: validación, intellisense y refactoring.
Desarrollo basado en componentes.
Uso de Anotaciones (metadatos): declarativa frente a imperativa.
Doble binding, se ha reconstruido según el patrón observable, las aplicaciones son
hasta cinco veces más rápidas.
La inyección de dependencias, carga dinámica de módulos.
Incluye compilación AoT (Ahead of Time - Antes de tiempo, que es una forma de
compilar todo el código JS, incluyendo plantillas de manera anticipada, restando
carga de trabajo al navegador) y también lazy-loading (descarga bajo demanda,
una manera de sólo descargar los recursos realmente necesarios en cada
momento).
Aparición de Angular Universal (herramienta de renderizado de Angular desde el
servidor), podemos ejecutar Angular en el servidor.
Aplicaciones híbridas, solución low cost para aplicaciones móviles.
Está cada vez más orientado a grandes desarrollos empresariales.

© JMA 2016. All rights reserved

26

Características
•

Velocidad y rendimiento
– Generación de código: Angular convierte sus plantillas en un código que está altamente
optimizado para las máquinas virtuales de JavaScript de hoy, brindándole todos los
beneficios del código escrito a mano con la productividad de un marco.
– Universal: Sirva la primera vista de su aplicación en Node.js, .NET, PHP y otros servidores
para renderización casi instantánea en solo HTML y CSS. También allana el camino para
sitios que optimizan para SEO.
– División del código: Las aplicaciones Angular se cargan rápidamente con el nuevo
enrutador de componentes, que ofrece división automática de códigos para que los
usuarios solo carguen el código requerido para procesar la vista que solicitan.

•

Plataformas cruzadas
– Aplicaciones web progresivas: Utilice las capacidades de la plataforma web moderna
para ofrecer experiencias similares a las de las aplicaciones de escritorio o nativas.
Instalación de alto rendimiento, fuera de línea y en cero pasos.
– Nativo: Cree aplicaciones móviles nativas con estrategias de Cordova, Ionic o
NativeScript.
– Escritorio: Cree aplicaciones instaladas en el escritorio en Mac, Windows y Linux
utilizando la misma metodología Angular que ha aprendido para la web y la capacidad
de acceder a las API nativas del sistema operativo.

© JMA 2016. All rights reserved

27

6

Características
•

Productividad
– Plantillas: Cree rápidamente vistas de IU con sintaxis de plantilla simple y
potente.
– Angular CLI: Herramientas de línea de comandos: comience a construir
rápidamente, agregue componentes y pruebas, y luego implemente al
instante.
– IDEs: Obtenga la finalización inteligente de códigos, errores instantáneos y
otros comentarios en editores e IDE populares.

•

Ciclo completo de desarrollo
– Pruebas: Con Karma para pruebas unitarias, puede saber si ha roto cosas cada
vez que guarda. Y Protractor hace que tus pruebas de escenarios (E2E) se
ejecuten más rápido y de manera estable.
– Animación: Cree coreografías y líneas de tiempo de animación complejas y de
alto rendimiento con muy poco código a través de la API intuitiva de Angular.
– Accesibilidad: Cree aplicaciones accesibles con componentes compatibles con
ARIA, guías para desarrolladores y una infraestructura de prueba incorporada.

© JMA 2016. All rights reserved

28

Angular adopta SEMVER
•
•

El sistema SEMVER (Semantic Versioning) es un conjunto de reglas para
proporcionar un significado claro y definido a las versiones de los
proyectos de software.
El sistema SEMVER se compone de 3 números, siguiendo la estructura
X.Y.Z, donde:
– X se denomina Major: indica cambios rupturistas
– Y se denomina Minor: indica cambios compatibles con la versión anterior
– Z se denomina Patch: indica resoluciones de bugs (compatibles)

•

•

Básicamente, cuando se arregla un bug se incrementa el patch, cuando se
introduce una mejora se incrementa el minor y cuando se introducen
cambios que no son compatibles con la versión anterior, se incrementa el
major.
De este modo cualquier desarrollador sabe qué esperar ante una
actualización de su librería favorita. Si sale una actualización donde el
major se ha incrementado, sabe que tendrá que ensuciarse las manos con
el código para pasar su aplicación existente a la nueva versión.

© JMA 2016. All rights reserved

29

7

Frecuencia de lanzamiento
• En general, se puede esperar el siguiente ciclo de publicación:
– Un lanzamiento importante (major) cada 6 meses
– 1-3 lanzamientos menores para cada lanzamiento principal
– El lanzamiento de un parche casi todas las semanas

• Para mejorar la calidad y permitir ver lo que vendrá después, se
realizan lanzamientos de versiones Beta y Release Candidatos (RC)
para cada versión mayor y menor.
• Dentro de la política de desaprobación, para ayudar a garantizar
que se tenga tiempo suficiente y una ruta clara de actualización, se
admite cada API obsoleta hasta al menos dos versiones principales
posteriores, lo que significa al menos 12 meses después de la
desaprobación.
• Ruptura de la secuencia:
– Pasa de la versión 2 → 4:
– El componente Router ya estaba en una 3.xx
© JMA 2016. All rights reserved

30

Novedades 4.0
•
•
•
•
•

Actualización de TypeScript 2.1
Uso de StrictNullChecks de TypeScript
Sintaxis if…else dentro de los templates (*ngIf)
Módulo de animación separado
Integración de Angular Universal como módulo de Angular
Core
• Mejoras de rendimiento gracias a FESM
npm install @angular/common@next @angular/compiler@next
@angular/compiler-cli@next @angular/core@next
@angular/forms@next @angular/http@next @angular/platformbrowser@next @angular/platform-browser-dynamic@next
@angular/platform-server@next @angular/router@next
@angular/animations@next --save
© JMA 2016. All rights reserved

31

8

Novedades 5.0
•
•
•
•

Actualización de TypeScript 2.4.2
Mejoras del compilador
API Angular Universal State Transfer y soporte DOM
Reconstruidos los pipes de números, fechas y monedas para
mejorar la internacionalización.
• Validaciones y actualizaciones de valores en `blur` o en` submit`.
• Actualizado el uso de RxJS a 5.5.2 o posterior
• Nuevos eventos del ciclo de vida del enrutador.
npm install @angular/animations@'^5.0.0' @angular/common@'^5.0.0'
@angular/compiler@'^5.0.0' @angular/compiler-cli@'^5.0.0'
@angular/core@'^5.0.0' @angular/forms@'^5.0.0'
@angular/http@'^5.0.0' @angular/platform-browser@'^5.0.0'
@angular/platform-browser-dynamic@'^5.0.0' @angular/platformserver@'^5.0.0' @angular/router@'^5.0.0' typescript@2.4.2 rxjs@'^5.5.2'
--save
© JMA 2016. All rights reserved

32

Novedades 6.0
•

•
•
•
•
•
•
•
•
•

Lanzamiento enfocado menos en el marco subyacente, y más en la cadena de
herramientas y en facilitar el movimiento rápido con Angular en el futuro,
sincronizando las versiones de Angular ( @angular/core, @angular/common,
@angular/compiler, etc.), Angular CLI y Angular Material + CDK.
Nuevos comandos CLI: ng update  y ng add 
Nuevos generadores CLI: application, library, universal
Angular Elements (Web Components)
Angular Material + CDK Components y generadores de componentes de arranque
Angular Material
CLI v6 ahora es compatible con espacios de trabajo que contienen múltiples
proyectos, como múltiples aplicaciones o bibliotecas.
Soporte para crear y construir bibliotecas.
Referenciado de proveedores en los servicios (Inyección de dependencias).
Actualizada la implementación de Animaciones para que ya no necesitemos el
polyfill de web animations.
Angular ha sido actualizado para usar v.6 de RxJS.

© JMA 2016. All rights reserved

33

9

Novedades 7.0
• Incorporación de avisos de CLI
• Mejoras Rendimiento de la aplicación
• Angular Material y el CDK:
– Desplazamiento virtual
– Arrastrar y soltar
– Mejorada la Accesibilidad de selecciones

• Angular Elements ahora admite la proyección de
contenido
• Actualización de TypeScript 3.1
• Angular ha sido actualizado para usar v.6.3 de RxJS.
© JMA 2016. All rights reserved

34

Actualización
• El equipo de Angular a creado la Angular
Update Guide para guiar a través del proceso
de actualización y para conocer los cambios
que se deben realizar en el código antes de
comenzar el proceso de actualización, los
pasos para actualizar la aplicación y la
información sobre cómo prepararse para
futuras versiones de Angular.
https://angular-update-guide.firebaseapp.com/
© JMA 2016. All rights reserved

35

10

TypeScript

© JMA 2016. All rights reserved

50

TypeScript
•

•

El lenguaje TypeScript fue ideado por Anders Hejlsberg – autor de Turbo
Pascal, Delphi, C# y arquitecto principal de .NET- como un supraconjunto
de JavaScript que permitiese utilizar tipos estáticos y otras características
de los lenguajes avanzados como la Programación Orientada a Objetos.
TypeScript es un lenguaje Open Source basado en JavaScript y que se
integra perfectamente con otro código JavaScript, solucionando algunos
de los principales problemas que tiene JavaScript:
– Falta de tipado fuerte y estático.
– Falta de “Syntactic Sugar” para la creación de clases
– Falta de interfaces (aumenta el acoplamiento ya que obliga a programar hacia
la implementación)
– Módulos (parcialmente resuelto con require.js, aunque está lejos de ser
perfecto)

•

TypeScript es un lenguaje con una sintaxis bastante parecida a la de C# y
Java, por lo que es fácil aprender TypeScript para los desarrolladores con
experiencia en estos lenguajes y en JavaScript.

© JMA 2016. All rights reserved

51

11

TypeScript
• Lo que uno programa con TypeScript, tras grabar los
cambios, se convierte en JavaScript perfectamente
ejecutable en todos los navegadores actuales (y antiguos),
pero habremos podido:
–
–
–
–

abordar desarrollos de gran complejidad,
organizando el código fuente en módulos,
utilizando características de auténtica orientación a objetos, y
disponer de recursos de edición avanzada del código fuente
(Intellisense, compleción de código, “snippets”, etc.), tanto en
Visual Studio, como en otros editores populares, como Sublime
Text, Eclipse, WebStorm, etc., cosa impensable hasta este
momento, pero factible ahora mismo gracias a los “plug-in” de
TypeScript disponibles para estos editores.

© JMA 2016. All rights reserved

52

TypeScript
• Amplia la sintaxis del JavaScript con la definición y
comprobación de:
–
–
–
–
–
–

Tipos básicos: booleans, number, string, Any y Void.
Clases e interfaces
Herencia
Genéricos
Módulos
Anotaciones

• Otra de las ventajas que otorga Typescript es que permite
comunicarse con código JavaScript ya creado e incluso
añadirle “tipos” a través de unos ficheros de definiciones
.d.ts que indican los tipos que reciben y devuelven las
funciones de una librería.
© JMA 2016. All rights reserved

53

12

TypeScript
• El TypeScript se traduce (“transpila”: compilar un lenguaje de alto
nivel a otro de alto nivel) a JavaScript cumpliendo el estándar
ECMAScript totalmente compatible con las versiones existentes.
• De hecho, el “transpilador” deja elegir la versión ECMAScript del
resultado, permitiendo adoptar la novedades mucho antes de que
los navegadores las soporten: basta con dejar el resultado en la
versión mas ampliamente difundida.
• El equipo de TypeScript provee de una herramienta de línea de
comandos para hacer esta compilación, se encuentra en npm y se
puede instalar con el siguiente comando:
– npm install -g typescript

• Podemos usarlo escribiendo
– tsc helloworld.ts

• Los diversos “plug-in” se pueden descargar en:
– https://www.typescriptlang.org
© JMA 2016. All rights reserved

54

Comandos tsc
• Compilación continua:
– tsc –w *.ts
– tsc --watch *.ts

• Fichero único de salida
– tsc --outFile file.js *.ts

• Compilación del proyecto:
-p DIRECTORY, --project DIRECTORY

• Control de directorios
--rootDir LOCATION  Ficheros de entrada
--outDir LOCATION  Ficheros de salida

• Directorio base de las rutas de los módulos:
--baseUrl

• Creación del fichero de configuración tsconfig.json:
--init
© JMA 2016. All rights reserved

55

13

Soportado por IDE’s/Utilidades
•
•
•
•
•
•
•
•

Visual Studio 2012 … – native (+msbuild)
Visual Studio Code
ReSharper – included
Sublime Text 2/3 – official plugin as a part of 1.5
release
Online Cloud9 IDE
Eclipse IDE
IntelliJ IDEA
Grunt, Maven, Gradle plugins

© JMA 2016. All rights reserved

56

Eclipse
•
•
•

Requiere tener instalado Node.js y TypeScript
Abrir Eclipse
Ir a Help → Install New Software
– Add the update site: http://eclipse-update.palantir.com/eclipse-typescript/
– Seleccionar e instalar TypeScript
– Re arrancar Eclipse

•
•

Opcionalmente, con el botón derecho en el proyecto seleccionar
Configure → Enable TypeScript Builder
En Project → Properties → Builders
–
–
–
–

•

Add new "Program" builder
Location: ...\tsc
Working Directory: ${project_loc}
Arguments: --source-map --outFile build.js **/*.ts

En Project → Properties → Build Automatically

© JMA 2016. All rights reserved

57

14

Historia

1/2015
10/2014 v1.4
9/2014 v1.3
v1.1

6/2013
v0.9

10/2012
v0.8

4/2015
v1.5beta

4/2014
v1.0

© JMA 2016. All rights reserved

59

Compatibilidad con ES6
Feb 2015

Today (TS 1.5)

https://kangax.github.io/compat-table/es6/#typescript
© JMA 2016. All rights reserved

60

15

Tipos de datos
•
•
•
•
•
•

•
•
•
•

Boolean:
Number:
String:
Enum:

var isDone: boolean = false;
var height: number = 6;
var name: string = "bob";
enum Color {Red, Green, Blue};
var c: Color = Color.Green;
Array:
var list:number[] = [1, 2, 3];
var list:Array = [1, 2, 3];
Any:
var notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
var list:any[] = [1, true, "free"];
Void:
function warnUser(msg: string): void { alert(msg); }
Null, Undefined, Never
Object: no es number, string, boolean, symbol, null, o undefined.
Clases e interfaces

© JMA 2016. All rights reserved

61

Definiciones
•

Variables globales:

•

Variables locales:

•

Variables constantes:

•

Inferencia de tipo:

var str: string = 'Inicio';
let x, y, z: number; // undefined
const LEVEL: number = 4;
let str = 'Inicio'; // string
let x = 1, y = 1; // number

•

Tuplas:
let tupla: [number, string] = [1, "cadena"];
let x : number = tupla[0];

•

Alias a los tipos:
type Tupla = [number, string];
let tupla: Tupla = [1, "cadena"];

© JMA 2016. All rights reserved

62

16

Sintaxis ampliada (ES6)
•

Cadenas (Interpolación y múltiples líneas)
let msg = `El precio de ${producto} es
de ${unidades * precio} euros`;

•

Bucle foreach:

•

Destructing

for (var i of [10, 20, 30) { window.alert(i); }
let x = 1;
let y = 2;
[x, y] = [y, x];
let point = {x: 1, y: 2};
{x, y} = point;

•

Auto nombrado:
let x = 1;
let y = 2;
let point = {x, y}; // {x: x, y: y}

© JMA 2016. All rights reserved

63

Control de tipos

© JMA 2016. All rights reserved

64

17

Funciones con tipo
•

Tipos para los parámetros y el valor de retorno:

•

Opcionales y Valores por defecto: Se pueden definir valores por defecto a
los parámetros en las funciones o marcarlos opcionales (undefined).

function add(x: number, y: number): number { return x+y; }

function(opcional?: any, valor = "foo") {...};

• Resto de los parámetros: Convierte una lista de parámetros en un array
de Any.
function f (x: number, y: number, ...a): number {
return (x + y) * a.length
}
f(1, 2, "hello", true, 7) === 9

• Operador de propagación: Convierte un array o cadena en una lista de
parámetros.
var str = "foo"
var chars = [ ...str ] // [ "f", "o", "o" ]
© JMA 2016. All rights reserved

66

Expresiones Lambda
Arrow functions
•

Funciones anónimas:
let rslt = data.filter(item => item.value > 0);
// equivale a: var rslt = data.filter(function (item) { return item.value > 0; });
data.forEach(elem => {
console.log(elem);
// …
});
var fn = (num1, num2) => num1 + num2;
pairs = evens.map(v => ({ even: v, odd: v + 1 }));

© JMA 2016. All rights reserved

67

18

Tipos Unión

© JMA 2016. All rights reserved

68

Null y Undefined (v2.1)
• En TypeScript, tanto el nulo como el sin definir tienen sus
propios tipos denominados undefined y null
respectivamente.
• Al igual que el vacío, no son muy útiles por su cuenta.
let u: undefined = undefined;
let N: null = null;

• Por defecto, null y undefined son subtipos de todos los
demás tipos, por lo que se puede asignar null o undefined a
cualquier otro tipo.
• Cuando se utiliza el flag --strictNullChecks, null y undefined
sólo se pueden asignar a void y sus respectivos tipos.
– Esto ayuda a evitar muchos errores comunes.
– Si se desea pasar en un tipo o nulo o indefinido, se puede
utilizar el tipo unión: tipo | null | undefined.
© JMA 2016. All rights reserved

69

19

Objetos JS

© JMA 2016. All rights reserved

70

Clases

© JMA 2016. All rights reserved

71

20

Constructor

© JMA 2016. All rights reserved

72

Compila a ES5

© JMA 2016. All rights reserved

73

21

También a ES6

© JMA 2016. All rights reserved

74

Modificadores
• De acceso:
– public  por defecto
– private
– protected (a partir de 1.3)

• De propiedades:
– set
– get

• Miembros de clase:
– static

• Clases y miembros abstractos:
– abstract

• Atributos de solo lectura:
– readonly (deben inicializarse en su declaración o en el constructor)

© JMA 2016. All rights reserved

75

22

Propiedades
class Employee {
private name: string;
get Name(): string { return this.name; }
set Name(newName: string) {
if (this.validate('Name')) {
this.name = newName;
this.NameChanged();
} else {
// …
}
}
// …
}
let employee = new Employee();
if (employee.Name === '') { employee.Name = 'Bob Smith'; }

© JMA 2016. All rights reserved

77

Herencia

© JMA 2016. All rights reserved

78

23

Genéricos

© JMA 2016. All rights reserved

79

Interfaces

© JMA 2016. All rights reserved

80

24

Interfaces: Como prototipos
• Definición en línea, sin interfaces:
function printLabel(labelledObj: {label: string}) {
console.log(labelledObj.label);
}
var myObj = {size: 10, label: "Size 10 Object"}; printLabel(myObj);

• Usando interfaces:
interface LabelledValue {
label: string;
}
function printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label);
}
var myObj = {size: 10, label: "Size 10 Object"}; printLabel(myObj);
© JMA 2016. All rights reserved

81

Interfaces: Propiedades opcionales
interface SquareConfig {
color?: string;
width?: number;
}
function createSquare(config: SquareConfig):
{color: string; area: number} {
var newSquare = {color: "white", area: 100};
if (config.color) {
newSquare.color = config.color;
}
if (config.width) {
newSquare.area = config.width * config.width;
}
return newSquare;
}
var mySquare = createSquare({color: "black"});
© JMA 2016. All rights reserved

82

25

Interfaces: Funciones y Arrays
•

Prototipos de Funciones
interface SearchFunc {
(source: string, subString: string): boolean;
}
var mySearch: SearchFunc;
mySearch = function(source: string, subStr: string) {
var result = source.search(subStr);
return result != -1;
}

•

Prototipos de Arrays
interface StringArray {
[index: number]: string;
}
var myArray: StringArray;
myArray = ["Bob", "Fred"];

© JMA 2016. All rights reserved

83

Módulos

© JMA 2016. All rights reserved

84

26

Módulos (ES6)
• Ficheros como módulos:
– Solo se puede importar lo previamente exportado.
– Es necesario importar antes de utilizar
– El fichero en el from sin extensión y ruta relativa (./ ../) o sin ruta
(NODE_MODULES)

• Exportar:
export public class MyClass { }
export { MY_CONST, myFunction, name as otherName }

• Importar:
import * from './my_module';
import * as MyModule from './my_module';
import { MyClass, MY_CONST, myFunction as func } from './my_module';

• Pasarelas: Importar y exportar (index.ts)
export { MyClass, MY_CONST, myFunction as func } from './my_module';
© JMA 2016. All rights reserved

85

Decoradores (ES7)

© JMA 2016. All rights reserved

87

27

Compatibilidad con Frameworks JS
• Ya existen ficheros de definiciones (.d.ts) para la mayoría de los
framework mas populares (http://definitelytyped.org/).
– npm install --save-dev @types/jquery

• Definiciones:
https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types

© JMA 2016. All rights reserved

88

Angular 2.0 – Escrito en TypeScript

© JMA 2016. All rights reserved

89

28

ARQUITECTURA DE ANGULAR

© JMA 2016. All rights reserved

134

Arquitectura de Angular

© JMA 2016. All rights reserved

137

29

Módulo
• La aplicaciones Angular son modulares.
• Angular dispone de su propio sistema de modularidad
llamado módulos Angular o NgModules .
• Cada aplicación Angular tiene al menos un módulo, el
módulo raíz, convencionalmente denominado AppModule.
• Mientras que el módulo de raíz puede ser el único módulo
en una aplicación pequeña, en la mayoría de las
aplicaciones existirán muchos más “módulos de
características”, cada uno como un bloque coherente de
código dedicado a un dominio de aplicación, un flujo de
trabajo o un conjunto estrechamente relacionado de
capacidades.
• El módulo Angular, una clase decorada con @NgModule, es
una característica fundamental de Angular.
© JMA 2016. All rights reserved

138

Bibliotecas Angular
• Los contenedores Angular son una colección de
módulos de JavaScript, se puede pensar en ellos
como módulos de biblioteca.
• Cada nombre de la biblioteca Angular comienza
con el prefijo @angular.
• Se pueden instalar con el gestor de paquetes
NPM e importar partes de ellos con instrucciones
import del JavaScript.
• De esta manera se está utilizando tanto los
sistemas de módulos de Angular como los de
JavaScript juntos.
© JMA 2016. All rights reserved

139

30

Módulos Angular vs.
Módulos JavaScript(ES6)/TypeScript
• JavaScript tiene su propio sistema de módulos para la
gestión de colecciones de objetos de JavaScript.
• Es completamente diferente y sin relación con el sistema de
módulos Angular.
• En JavaScript cada archivo es un módulo y todos los objetos
definidos en el archivo pertenece a ese módulo.
• El módulo declara algunos objetos para ser públicos
marcándolas con la palabra clave export.
• Los módulos de JavaScript usan declaraciones de
importación para tener acceso a los objetos públicos
(exportados) de dichos módulos.
• Se trata de dos sistemas diferentes y complementarios de
módulos.
© JMA 2016. All rights reserved

140

Metadatos
• Angular ha optado por sistema declarativo de definición de sus
elementos mediante el uso de decoradores (ES7), también
conocidos como anotaciones o metadatos.
• Los Decoradores son funciones que modifican las clases de
JavaScript.
• Angular suministra decoradores que anotan a las clases con
metadatos y le indican lo que significan dichas clases y cómo debe
trabajar con ellas.
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
exports: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
© JMA 2016. All rights reserved

141

31

Componentes
• Un componente controla una parte de la pantalla denomina vista.
• Se puede considerar que un componte es una clase con interfaz de
usuario.
• Reúne en un único elemento: el código (clase que expone datos y
funcionalidad), su representación (plantilla) y su estética (CSS).
• El código interactúa con la plantilla a través del enlazado dinámico.
• Una vez creado, un componente es como una nueva etiqueta HTML
que puede ser utilizada en otras plantillas.
• Los componentes son elementos estancos que establecen una
frontera clara y concisa de entrada/salida.
• Angular crea, actualiza y destruye los componentes según el
usuario se mueve a través de la aplicación.
• Angular permite personalizar mediante el uso de enganches (hooks)
lo que pasa en cada fase del ciclo de vida del componente.
© JMA 2016. All rights reserved

142

Plantillas
•
•
•

Las plantillas contienen la representación visual de los componentes.
Son segmentos escritos en HTML ampliado con elementos suministrados
por Angular como las directivas, marcadores, pipes, …
Cuentan con la lógica de presentación pero no permiten la codificación:
los datos y la funcionalidad se los suministra la clase del componente.
Una plantilla puede utilizar otros
componentes, actuan como
contenedores, dichos componentes
pueden contener a su vez otros
componentes. Esto crea un árbol de
componentes: el modelo de composición.

© JMA 2016. All rights reserved

143

32

Enlace de datos
• Automatiza, de una forma declarativa, la comunicación entre los
controles HTML de la plantilla y las propiedades y métodos del
código del componente.
• Requieren un nuevo modelo mental declarativo frente al imperativo
tradicional.
• El enlace de datos también permite la comunicación entre los
componentes principales y secundarios.

© JMA 2016. All rights reserved

144

Enlace de datos
• La comunicación ente
Componente y Plantilla
puede ser:
– Unidireccional:
• Datos (C→P)
– Interpolación
– Propiedades

• Comandos (P→C)
– Eventos

– Bidireccional:
• Datos (P→C)
– Directivas
© JMA 2016. All rights reserved

145

33

Directivas
• Las directivas son marcas en los elementos del árbol DOM, en los
nodos del HTML, que indican al Angular que debe asignar cierto
comportamiento a dichos elementos o transformarlos según
corresponda.
• Podríamos decir que las directivas nos permiten añadir
comportamiento dinámico al árbol DOM, haciendo uso de las
directivas propias del Angular o extender la funcionalidad hasta
donde necesitemos creando las nuestras propias.
• La recomendación es que el único sitio donde se puede manipular
el árbol DOM debe ser en las directivas, para que entre dentro del
ciclo de vida de compilación, binding y renderización del HTML que
sigue el Angular.
• Aunque un componente es técnicamente una directiva-conplantilla, conceptualmente son dos elementos completamente
diferentes.
© JMA 2016. All rights reserved

146

Pipes
• El resultado de una expresión puede requerir alguna
transformación antes de estar listo para mostrarla en
pantalla: mostrar un número como moneda, que el texto
pase a mayúsculas o filtrar una lista y ordenarla.
• Los Pipes de Angular, anteriormente denominados filtros,
son simples funciones que aceptan un valor de entrada y
devuelven un valor transformado. Son fáciles de aplicar
dentro de expresiones de plantilla, usando el operador
tubería (|).
• Son una buena opción para las pequeñas transformaciones,
dado que al ser encadenables un conjunto de
transformaciones pequeñas pueden permitir una
transformación compleja.
© JMA 2016. All rights reserved

147

34

Servicios
• Los servicios en Angular son una categoría muy amplia que abarca
cualquier valor, función o característica que necesita una aplicación.
• Casi cualquier cosa puede ser un servicio, aunque típicamente es
una clase con un propósito limitado y bien definido, que debe hacer
algo específico y hacerlo bien.
• Angular no tiene una definición especifica para los servicios, no hay
una clase base o anotación, ni un lugar para registrarlos.
• Los servicios son fundamentales para cualquier aplicación Angular y
los componentes son grandes consumidores de servicios.
• La responsabilidad de un componente es implementar la
experiencia de los usuarios y nada más: expone propiedades y
métodos para el enlace desde la plantilla, y delega todo lo demás
en las directivas (manipulación del DOM) y los servicios (lógica de
negocio).
© JMA 2016. All rights reserved

148

Inyección de dependencia
•
•
•
•

•

La Inyección de Dependencias (DI) es un mecanismo que proporciona
nuevas instancias de una clase con todas las dependencias que requiere
plenamente formadas.
La mayoría de dependencias son servicios, y Angular usa la DI para
proporcionar nuevos componentes con los servicios ya instanciados que
necesitan.
Gracias a TypeScript, Angular sabe de qué servicios depende un
componente con tan solo mirar su constructor.
El Injector es el principal mecanismo detrás de la DI. A nivel interno, un
inyector dispone de un contenedor con las instancias de servicios que crea
él mismo. Si una instancia no está en el contenedor, el inyector crea una
nueva y la añade al contenedor antes de devolver el servicio a Angular, por
eso los servicios son singletons en el ámbito de su inyector.
El provider es cualquier cosa que puede crear o devolver un servicio,
típicamente, la propia clase que define el servicio. Los providers pueden
registrarse en cualquier nivel del árbol de componentes de la aplicación a
través de los metadatos de componentes.

© JMA 2016. All rights reserved

149

35

Web Components
•

•

•

Los Web Components nos ofrecen un estándar que va enfocado a la creación de
todo tipo de componentes utilizables en una página web, para realizar interfaces
de usuario y elementos que nos permitan presentar información (o sea, son
tecnologías que se desarrollan en el lado del cliente). Los propios desarrolladores
serán los que puedan, en base a las herramientas que incluye Web Components
crear esos nuevos elementos y publicarlos para que otras personas también los
puedan usar.
Los Web Components son una reciente incorporación al HTML5 que, si siguen
evolucionando al ritmo al que lo están haciendo, pueden suponer el mayor cambio
en el mundo web en años y solucionar de golpe varios problemas históricos de
HTML.
El estándar, en proceso de definición, en realidad, se compone de 4 subelementos
complementarios, pero independientes entre si:
–
–
–
–

•

Custom Elements http://w3c.github.io/webcomponents/spec/custom/
Templates https://www.w3.org/TR/html5/scripting-1.html#the-template-element
Shadow DOM https://www.w3.org/TR/shadow-dom/
HTML Imports http://w3c.github.io/webcomponents/spec/imports/

Cualquiera de ellos puede ser usado por separado, lo que hace que la tecnología
de los Web Elements sea, además de muy útil, muy flexible.

© JMA 2016. All rights reserved

152

Web Components
• Templates: son fragmentos de HTML que representan al
componente de modo que cuando se haga referencia al
componente se usará esta plantilla.
• HTML Import: es la posibilidad de incluir un HTML dentro
de otro mediante un tag . De este modo el template de un Web
Component formará parte del otro.
• Shadow DOM: permite encapsular el subarbol DOM de un
componente, de modo que la interacción desde fuera y
hacia dentro está controlada. Es importante para que los
componentes no entren en conflictos al formar parte de la
misma página.
• Custom Elements: para la definición de Tags específicos
que representan a los web components que se han creado.
© JMA 2016. All rights reserved

153

36

Angular Elements
•
•

•
•

Los Angular Elements son componentes Angular empaquetados como Web
Components, también conocidos como elementos personalizados, el estándar web
para definir nuevos elementos HTML de una forma independiente del framework.
Los Web Components son una característica de la Plataforma Web actualmente
compatible con las últimas versiones Chrome, Opera y Safari, y están disponibles
para otros navegadores a través de polyfills. Un elemento personalizado extiende
HTML al permitir definir una etiqueta cuyo contenido está creado y controlado por
código JavaScript. El navegador mantiene una serie CustomElementRegistry de
elementos personalizados definidos (o componentes web), que asigna una clase
de JavaScript instanciable a una etiqueta HTML.
El paquete @angular/elements exporta una API createCustomElement() que
proporciona un puente desde la interfaz de componente y la funcionalidad de
detección de cambios de Angular a la API DOM integrada.
Transformar un componente en un elemento personalizado hace que toda la
infraestructura Angular requerida esté disponible para el navegador. La creación
de un elemento personalizado es simple y directa, y conecta automáticamente la
vista definida por el componente con la detección de cambios y el enlace de datos,
asignando la funcionalidad Angular a los equivalentes de HTML nativos
correspondientes.

© JMA 2016. All rights reserved

154

Model View ViewModel (MVVM)
•

El Modelo es la entidad que representa el concepto de negocio.

•

La Vista es la representación gráfica del control o un conjunto de controles
que muestran el Modelo de datos en pantalla.

•

La VistaModelo es la que une todo. Contiene la lógica del interfaz de
usuario, los comandos, los eventos y una referencia al Modelo.
Eventos

Vista

Métodos

Eventos

VistaModelo

Métodos

Modelo

Data Binding
Comandos
© JMA 2016. All rights reserved

155

37

Soporte de navegador
Navegador

Versiones compatibles

Chrome

Última

Firefox

Última

Edge

Últimas 2 versiones

IE

11, 10, 9

IE Mobile

11

Safari

Últimas 2 versiones

iOS

Últimas 2 versiones

Android

Nougat (7.0)
Marshmallow (6.0)
Lollipop (5.0, 5.1)
KitKat (4.4)

© JMA 2016. All rights reserved

156

HERRAMIENTAS DE DESARROLLO

© JMA 2016. All rights reserved

157

38

IDEs
• Visual Studio Code - http://code.visualstudio.com/
– VS Code is a Free, Lightweight Tool for Editing and Debugging Web
Apps.

• StackBlitz - https://stackblitz.com
– The online IDE for web applications. Powered by VS Code and GitHub.

• Angular IDE by Webclipse https://www.genuitec.com/products/angular-ide
– Built first and foremost for Angular. Turnkey setup for beginners;
powerful for experts.

• IntelliJ IDEA - https://www.jetbrains.com/idea/
– Capable and Ergonomic Java * IDE

• Webstorm - https://www.jetbrains.com/webstorm/
– Lightweight yet powerful IDE, perfectly equipped for complex clientside development and server-side development with Node.js
© JMA 2016. All rights reserved

158

Instalación de utilidades
Consideraciones previas
– Las utilidades son de línea de comandos.
– Para ejecutar los comandos es necesario abrir la consola comandos (Símbolo
del sistema)
– Siempre que se realice una instalación o creación es conveniente “Ejecutar
como Administrador” para evitar otros problemas.
– En algunos casos el firewall de Windows, la configuración del proxy y las
aplicaciones antivirus pueden dar problemas.

GIT: Software de control de versiones
– Descargar e instalar: https://git-scm.com/
– Verificar desde consola de comandos:
• git

Node.js: Entorno en tiempo de ejecución
– Descargar e instalar: https://nodejs.org
– Verificar desde consola de comandos:
• node --version
© JMA 2016. All rights reserved

159

39

npm: Node Package Manager
•

Aunque se instala con el Node es conveniente actualizarlo:

•

Verificar desde consola de comandos:

•

Configuración:

– npm update -g npm
– npm --version
– npm config edit
– proxy=http://usr:pwd@proxy.dominion.com:8080  Símbolos: %HEX ASCII

•

Generar fichero de dependencias package.json:

•

Instalación de paquetes:

– npm init
– npm install -g grunt-cli grunt-init karma karma-cli  Global (CLI)
– npm install jasmine-core tslint --save --save-dev
– npm install  Dependencias en package.json

•

Arranque del servidor:
– npm start

© JMA 2016. All rights reserved

160

Generación del esqueleto de
aplicación
• Configurar un nuevo proyecto de Angular 2 es un proceso
complicado y tedioso, con tareas como:
– Crear la estructura básica de archivos y bootstrap
– Configurar SystemJS o WebPack para transpilar el código
– Crear scripts para ejecutar el servidor de desarrollo, tester,
publicación, …

• Disponemos de diferentes opciones de asistencia:
– Proyectos semilla (seed) disponibles en github
– Generadores basados en Yeoman
– Herramienta oficial de gestión de proyectos, Angular CLI.

• Angular CLI, creada por el equipo de Angular, es una Command Line
Interface que permite generar proyectos y plantillas de código
desde consola, así como ejecutar un servidor de desarrollo o lanzar
los tests de la aplicación. (https://cli.angular.io/)
– npm install -g @angular/cli@latest
© JMA 2016. All rights reserved

161

40

Proyectos semilla
•

Proyectos semilla:
–
–
–
–
–
–
–

•

https://github.com/angular/quickstart
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

Generadores de código basados en Yeoman
(http://yeoman.io/generators):
– https://github.com/FountainJS/generator-fountain-angular2
– https://github.com/ericmdantas/generator-ng-fullstack

•

NOTA: Es conveniente verificar si están actualizados a la última versión de
Angular 2, pueden estar desactualizados.

© JMA 2016. All rights reserved

162

Creación y puesta en marcha
• Acceso al listado de comandos y opciones
– $ ng help

• Nuevo proyecto
– $ ng new myApp
– Esto creará la carpeta myApp con un esqueleto de proyecto ya
montado según la última versión de Angular y todo el trabajo
sucio de configuración de WebPack para transpilar el código y
generar un bundle, configuración de tests, lint y typescript, etc.
– Además, instala todas las dependencias necesarias de npm e
incluso inicializa el proyecto como un repositorio de GIT.

• Servidor de desarrollo
– ng serve
– Esto lanza tu app en la URL http://localhost:4200 y actualiza el
contenido cada vez que guardas algún cambio.
© JMA 2016. All rights reserved

163

41

Generar código
•
•

Hay elementos de código que mantienen una cierta estructura y no
necesitas escribirla cada vez que creas un archivo nuevo.
El comando generate permite generar algunos de los elementos
habituales en Angular.
–
–
–
–
–
–
–
–
–

Componentes:
Directivas:
Pipe:
Servicios:
Clases:
Interface:
Enumerados:
Módulos:
Guardian (rutas):

--module my-module
--project my-lib

ng generate component my-new-component
ng g directive my-new-directive
ng g pipe my-new-pipe
ng g service my-new-service
ng g class my-new-class
ng g interface my-new-interface
ng g enum my-new-enum
ng g module my-module
ng generate guard my-guard
Indica el modulo si no es el principal
Indica el proyecto si no es el principal

© JMA 2016. All rights reserved

164

Schematics en Angular CLI (v.6)
• Schematics es una herramienta de flujo de trabajo para la web
moderna; permite aplicar transformaciones al proyecto, como crear
un nuevo componente, actualizar el código para corregir cambios
importantes en una dependencia, agregar una nueva opción o
marco de configuración a un proyecto existente.
• Generadores de componentes de arranque Angular Material:
– Un componente de inicio que incluye una barra de herramientas con
el nombre de la aplicación y la navegación lateral:
• ng generate @angular/material:material-nav --name=my-nav

– Un componente de panel de inicio que contenga una lista de tarjetas
de cuadrícula dinámica:
• ng generate @angular/material:material-dashboard --name=my-dashboard

– Un componente de tabla de datos de inicio que está pre configurado
con un datasource para ordenar y paginar:
• ng generate @angular/material:material-table --name=my-table

© JMA 2016. All rights reserved

166

42

Nuevos comandos (v.6)
•

ng update  analiza el package.json de la aplicación actual y
utiliza la heurísticas de Angular para recomendar y realizar las
actualizaciones que necesita la aplicación.
– npm install -g @angular/cli
– npm install @angular/cli
– ng update @angular/cli

•

ng add  permite agregar nuevas capacidades al proyecto y
puede actualizar el proyecto con cambios de configuración, agregar
dependencias adicionales o estructurar el código de inicialización
específico del paquete.
– ng add @angular/pwa - Convierte la aplicación en un PWA agregando un
manifiesto de aplicación y un service worker.
– ng add @ng-bootstrap/schematics - Agrega ng-bootstrap a la aplicación.
– ng add @angular/material - Instala y configura Angular Material y el estilo, y
registrar nuevos componentes de inicio en ng generate.
– ng add @angular/elements - Agrega el polyfill document-register-element.js y
las dependencias necesarios para los Angular Elements.

© JMA 2016. All rights reserved

167

Pruebas
• Son imprescindibles en entornos de calidad: permite
ejecutar las pruebas unitarias, las pruebas de extremo
a extremo o comprobar la sintaxis.
• Para comprobar la sintaxis: Puedes ejecutar el
analizador con el comando:
– ng lint

• Para ejecutar tests unitarios: Puedes lanzar los tests
unitarios con karma con el comando:
– ng test

• Para ejecutar tests e2e: Puedes lanzar los tests end to
end con protractor con el comando:
– ng e2e
© JMA 2016. All rights reserved

168

43

Despliegue
• Construye la aplicación en la carpeta /dist
– ng build
– ng build --dev

• Paso a producción, construye optimizándolo todo
para producción
– ng build --prod
– ng build --prod --env=prod
– ng build --target=production --environment=prod

• Precompila la aplicación
– ng build --prod --aot
© JMA 2016. All rights reserved

169

Estructura de directorios de soporte
src
e2e
 app.e2e-spec.ts
 app.po.ts
 tsconfig.json











.editorconfig
.gitignore
angular.json
karma.conf.js
package.json
protractor.conf.js
README.md
tsconfig.json
tslint.json

• src: Fuentes de la aplicación
• e2e: Test end to end
• Ficheros de configuración de
librerías y herramientas
• Posteriormente aparecerán los
siguientes directorios:
– node_modules: Librerías y
herramientas descargadas
– dist: Resultado para publicar en
el servidor web
– coverage: Informes de
cobertura de código

© JMA 2016. All rights reserved

171

44

Estructura de directorios de aplicación
•

 app







app.component.css
app.component.html
app.component.spec.ts
app.component.ts
app.module.ts
index.ts

 assets
 environments













environment.prod.ts
environment.ts

favicon.ico
index.html
main.ts
polyfills.ts
styles.css
test.ts
tsconfig.app.json
tsconfig.spec.json
typings.d.ts

•
•
•
•
•
•
•
•
•

app: Carpeta que contiene los ficheros
fuente principales de la aplicación.
assets: Carpeta con los recursos que se
copiaran a la carpeta build.
environments: configuración de los
diferentes entornos.
main.ts: Arranque del módulo principal de la
aplicación. No es necesario modificarle.
favicon.ico: Icono para el navegador.
index.html: Página principal (SPA).
style.css: Se editará para incluir CSS global de
la web, se concatena, minimiza y enlaza en
index.html automáticamente.
test.ts: pruebas del arranque.
polyfills.js: importación de los diferentes
módulos de compatibilidad ES6 y ES7.
Tsconfig.xxxx.json: Configuración del
compilador TypeScript para la aplicación y las
pruebas.

© JMA 2016. All rights reserved

172

Webpack
• Webpack (https://webpack.github.io/) es un empaquetador de
módulos, es decir, permite generar un archivo único con todos
aquellos módulos que necesita la aplicación para funcionar.
• Toma módulos con dependencias y genera archivos estáticos
correspondientes a dichos módulos.
• Webpack va mas allá y se ha convertido en una herramienta muy
versátil. Entre otras cosas, destaca que:
– Puede generar solo aquellos fragmentos de JS que realmente necesita
cada página.
• Dividir el árbol de dependencias en trozos cargados bajo demanda
• Haciendo más rápida la carga inicial

– Tiene varios loaders para importar y empaquetar también otros
recursos (CSS, templates, …) así como otros lenguajes (ES6 con Babel,
TypeScript, SaSS, etc).
– Sus plugins permiten hacer otras tareas importantes como por
ejemplo minimizar y ofuscar el código.
© JMA 2016. All rights reserved

174

45

Librerías de terceros
•

Descargar

•

Referenciar código en angular.json

– npm install bootstrap --save
"scripts": [
"node_modules/jquery/dist/jquery.js",
{"input": "./node_modules/bootstrap/dist/js/bootstrap.js"},
]

•

Referenciar estilos en angular.json
"styles": [
{"input": "./node_modules/bootstrap/dist/css/bootstrap.css"},
"styles.css"
]

•

Inclusión de ficheros:
"assets": [
"src/assets",
"src/favicon.ico",
{ "glob": "**/*", "input": "./node_modules/bootstrap/dist/font", "output": "/" }
],

© JMA 2016. All rights reserved

177

Glifos
• Font Awesome (https://fontawesome.com/)
• Instalar:
npm install --save @fortawesome/fontawesome-free

• Configurar en angular.json
"build": {
"options": {
"styles": [
"node_modules/@fortawesome/fontawesome-free/css/all.css"
"styles.css"
],
}
}

• Probar:

{{title}}

© JMA 2016. All rights reserved 178 46 GIT • Preséntate a Git – git config --global user.name "Your Name Here“ – git config --global user.email your_email@youremail.com • Crea un repositorio central • Conecta con el repositorio remoto – https://github.com/ – git remote add origin https://github.com/username/myproject.git – git push -u origin master • Actualiza el repositorio con los cambios: – git commit -m "first commit" – git push • Para clonar el repositorio: • Para obtener las últimas modificaciones: – git clone https://github.com/username/myproject.git local-dir – git pull © JMA 2016. All rights reserved 179 MÓDULOS © JMA 2016. All rights reserved 180 47 Módulos • • • • • • Los módulos son una buena manera de organizar la aplicación y extenderla con las capacidades de las bibliotecas externas. Los módulos Angular consolidan componentes, directivas y pipes en bloques cohesivos de funcionalidad, cada uno centrado en un área de características, un dominio de negocio de la aplicación, un flujo de trabajo o una colección común de los servicios públicos. Los módulos pueden añadir servicios a la aplicación, que pueden ser desarrollados internamente, tales como el registrador de aplicación, o pueden provenir de fuentes externas, tales como el enrutador de Angular y el cliente HTTP. Muchas bibliotecas de Angular son módulos (por ejemplo: FormsModule, HttpModule, RouterModule). Muchas bibliotecas de terceros están disponibles como módulos Angular (por ejemplo: Bootstrap, Material Design, Ionic, AngularFire2 ). Los módulos pueden ser cargados cuando se inicia la aplicación o de forma asíncrona por el router. © JMA 2016. All rights reserved 181 Módulo • Un módulo Angular es una clase adornada con la función decoradora @NgModule: objeto de metadatos que indica cómo Angular compila y ejecuta código del módulo. – Declara qué componentes, directivas y pipes pertenecen al módulo. – Expone algunos de ellos de manera pública para que puedan ser usados externamente por otras plantillas. – Importar otros módulos con los componentes, las directivas y las pipes necesarios para los componentes de este módulo. – Se pueden agregar proveedores de servicios a los inyectores de dependencia de aplicación que cualquier componente de la aplicación podrá utilizar. • • • Cada aplicación Angular tiene al menos un módulo, el módulo raíz, convencionalmente denominado AppModule. Es el responsable del arranque (Bootstrap) de la aplicación. El módulo principal es todo lo que se necesita en una aplicación sencilla con unos pocos componentes. A medida que crece la aplicación, se refactoriza el módulo raíz en módulos de características, los cuales representan colecciones de funcionalidad relacionada, que luego se importan al módulo de raíz . © JMA 2016. All rights reserved 182 48 @NgModule import { NgModule } from '@angular/core'; • imports: Especifica una lista de módulos cuyos componentes / directivas / pipes deben estar disponibles para las plantillas de este módulo. • declarations: Especifica una lista de componentes / directivas / pipes que pertenecen a este módulo (son privadas al módulo si no se exportan). • providers: Define el conjunto de objetos inyectables que están disponibles en el inyector de este módulo. • exports: Especifica una lista de componentes / directivas / pipes que se pueden utilizar dentro de las plantilla de cualquier componente que importe este módulo Angular. • bootstrap: Define los componentes que deben ser arrancados cuando se arranque el módulo, se añadirán automáticamente a entryComponents. © JMA 2016. All rights reserved 183 Módulo de raíz import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { } • BrowserModule: módulo necesario para las aplicaciones de navegador. – – Registra los proveedores de servicios de aplicaciones críticas. También incluye directivas/pipes comunes como NgIf y NgFor que se convierten inmediatamente en visibles y utilizables por cualquiera de las plantillas de los componentes del módulo. © JMA 2016. All rights reserved 184 49 Módulos TypeScript/JavaScript(ES6) • No confundir con los módulos de Angular. • Es necesario importar todas las clases, funciones, … que se vayan a utilizar en el código: import { Component, OnInit } from '@angular/core'; import { AppComponent } from './app.component'; • Se pueden importar todos los elementos del módulo {*} aunque no suele ser recomendable. • Hay que referenciar la ruta relativa al fichero del módulo sin extensión. • Para poder importar algo es necesario haberlo marcado previamente como importable con export. export class AppComponent { © JMA 2016. All rights reserved 185 Módulos de características • Generar el módulo: • Importar CommonModule en vez de BrowserModule • • Implementar los diferentes elementos del módulo Exportar lo elementos compartidos: ng generate module myCore import { CommonModule } from '@angular/common'; @NgModule({ // … exports: [MyCoreComponent, MyCorePipe] }) export class MyCoreModule { } • Importar el módulo: import { MyCoreModule } from './my-core/my-core.module'; @NgModule({ //… imports: [ //… MyCoreModule] }) export class AppModule { } • Utilizar las nuevas características obtenidas. © JMA 2016. All rights reserved 186 50 Módulos de características • Hay cinco categorías generales de módulos de características que tienden a pertenecer a los siguientes grupos: – Módulos de características de dominio: ofrecen una experiencia de usuario dedicada a un dominio de aplicación particular, exponen el componente superior y ocultan los subcomponentes. – Módulos de características enrutados: los componentes principales son los objetivos de las rutas de navegación del enrutador. – Módulos de enrutamiento: proporciona la configuración de enrutamiento para otro módulo y separa las preocupaciones de enrutamiento de su módulo complementario. – Módulos de características del servicio: brindan servicios de utilidad como acceso a datos y mensajería. – Módulos de características de widgets: hace que los componentes, las directivas y los pipes estén disponibles para los módulos externos (bibliotecas de componentes de UI) © JMA 2016. All rights reserved 187 Prevenir la reimportación • • Hay módulos que solo se deben importar en el módulo raíz y una sola vez. Para prevenir la reimportación es necesario crear el siguiente constructor en el módulo: constructor (@Optional() @SkipSelf() parentModule: MyCoreModule) { if (parentModule) { throw new Error( 'MyCoreModule is already loaded. Import it in the AppModule only'); } } • • La inyección podría ser circular si Angular busca MyCoreModule en el inyector actual. El decorador @SkipSelf significa “buscar MyCoreModule en un inyector antecesor, por encima de mí en la jerarquía del inyector“. Si el inyecto no lo encuentra, como debería ser, suministrará un null al constructor. El decorador @Optional permite que el constructor no reciba el parámetro. © JMA 2016. All rights reserved 188 51 Arranque de la aplicación (v4) // main.ts import { enableProdMode } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platformbrowser-dynamic'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; if (environment.production) { enableProdMode(); } platformBrowserDynamic().bootstrapModule(AppModule); © JMA 2016. All rights reserved 190 SPA (v4) Curso de Angular2 © JMA 2016. All rights reserved 192 52 Módulos usados frecuentemente NgModule Importar desde Por qué lo usas BrowserModule @angular/platform-browser Para ejecutar la aplicación en un navegador CommonModule @angular/common Para usar directivas comunes como NgIf y NgFor FormsModule @angular/forms Cuando crea formularios controlados por plantilla (incluye NgModel) ReactiveFormsModule @angular/forms Al construir formularios reactivos RouterModule @angular/router Para enrutamiento y cuando se quiere utilizar RouterLink, .forRoot() y .forChild() HttpClientModule @angular/common/http Para acceder a un servidor © JMA 2016. All rights reserved 193 SERVICIOS © JMA 2016. All rights reserved 194 53 Servicios • Los servicios en Angular es una categoría muy amplia que abarca cualquier valor, función o característica que necesita una aplicación. • Angular no tiene una definición especifica para los servicios, no hay una clase base ni un lugar para registrarlos, son simples Clases. • Tienen la siguiente particularidad: – @Injectable: Este decorador avisa a Angular de que el servicio espera utilizar otros servicios y genera los metadatos que necesita el servicio para detectar la Inyección de Dependencias (DI) en el constructor. No es obligatorio ponerlo si el servicio no tiene IoC de otros servicios, pero es recomendable para evitar errores si en el futuro se añade alguna dependencia. – Dependency Injection (DI) en el Constructor: Aquí aprovechamos las bondades de TypeScript para pasar explícitamente un objeto con tipo en el constructor. De este modo, Angular es capaz de inferir la Inyección de Dependencias. © JMA 2016. All rights reserved 195 Servicio ng generate service datos import {Injectable} from '@angular/core'; import { Logger } from '../core/logger.service'; @Injectable() export class DatosService { modelo = {}; constructor(public logger: Logger){} metodo1() { … } metodo2() { … } } © JMA 2016. All rights reserved 196 54 Inyección de dependencia • • • • • La Inyección de Dependencias (DI) es un mecanismo que proporciona nuevas instancias de una clase con todas las dependencias que requiere plenamente formadas. La mayoría de dependencias son servicios, y Angular usa la DI para proporcionar nuevos componentes con los servicios ya instanciados que necesitan. Gracias a TypeScript, Angular sabe de qué servicios depende un componente con tan solo mirar su constructor. El Injector es el principal mecanismo detrás de la DI. A nivel interno, un inyector dispone de un contenedor con las instancias de servicios que crea él mismo. Si una instancia no está en el contenedor, el inyector crea una nueva y la añade al contenedor antes de devolver el servicio a Angular, por eso se dice que los servicios son singletons en el ámbito de su inyector. El provider es cualquier cosa que puede crear o devolver un servicio, como la propia clase que define el servicio. Los providers pueden registrarse en cualquier nivel del árbol de componentes de la aplicación a través de los metadatos de componentes. © JMA 2016. All rights reserved 197 Registrar en el inyector • Globalmente, único para todo el módulo: import { DatosService } from './datos.service'; @NgModule({ … providers: [DatosService, Logger], … }) export class AppModule { } • En el componente, solo estará disponibles para el componente y su contenido: import { DatosService } from './datos.service'; @Component({ … providers: [DatosService, Logger], … }) export class AppComponent { © JMA 2016. All rights reserved 198 55 Proveedores • Un proveedor proporciona la versión concreta en tiempo de ejecución de un valor de dependencia. El inyector se basa en los proveedores para crear instancias de los servicios que inyecta en componentes y otros servicios. • Proveedor simplificado: providers: [MyService] • Proveedor de objeto literal: providers:[{ provide: alias, useClass: MyService}] • Una instancia para dos proveedores: providers: [ NewLogger, { provide: OldLogger, useExisting: NewLogger}] • Añadir a un proveedor múltiple: { provide: NG_VALIDATORS, useExisting: MyDirective, multi: true } • Proveedor de valor ya instanciado: { provide: VERSION, useValue: '2.1.0.234' }] © JMA 2016. All rights reserved 199 Factorías • • A veces tenemos que crear el valor dependiente dinámicamente, en base a información que no tendremos hasta el último momento posible. Tal vez la información cambia varias veces en el transcurso de la sesión de navegación. Supongamos también que el servicio inyectable no tiene acceso independiente a la fuente de esta información. Esta situación requiere de un proveedor factoría: función que genera la instancia del servicio. export class DatosService { constructor(logger: Logger, isAuthorized: boolean){} // … } export let DatosServiceFactory = (logger: Logger, userService: UserService) => { return new DatosService(logger, userService.user.isAuthorized); }; providers: [{provide: DatosService, useFactory: DatosServiceFactory, deps: [Logger, UserService] }] © JMA 2016. All rights reserved 200 56 Auto referenciado de proveedores (v.6) • Se puede especificar que el servicio debe proporcionarse en el inyector raíz: agrega un proveedor del servicio al inyector del módulo principal, estos proveedores están disponibles para todas las clases en la aplicación, siempre que tengan el token de búsqueda. @Injectable({ providedIn: 'root', }) • También es posible especificar que se debe proporcionar un módulo en particular: @Injectable({ providedIn: MyCoreModule, }) • Dan a Angular la capacidad de eliminar servicios del producto final que no se usan en su aplicación. © JMA 2016. All rights reserved 201 Dependencias que no son de clase • La inyección utiliza los nombres de las clase. A veces se quiere inyectar algo que no tiene una representación en tiempo de ejecución: interfaces, genéricos, arrays, … • En dichos casos es necesario crear una cadena o un token y referenciar con el decorador @Inject. • Mediante cadenas: providers: [{ provide: 'VERSION', useValue: '2.1.0.234' }] constructor(@Inject('VERSION') public version: string) • InjectionToken permite crear un token que se puede utilizar en un proveedor de DI, donde T que es el tipo de objeto que será devuelto por el Inyector. Esto proporciona un nivel adicional de seguridad de tipo. export const VERSION = new InjectionToken('Version'); providers: [{ provide: VERSION, useValue: '2.1.0.234' }] constructor(@Inject(VERSION) public version: string) © JMA 2016. All rights reserved 202 57 Dependencias opcionales • Se puede indicar que se inyecte solo si existe la clase del servicio: import { Optional } from '@angular/core'; class AnotherService{ constructor(@Optional() private logger: Logger) { if (this.logger) { this.logger.log("I can log!!"); } } } • Es importante que el componente o servicio este preparado para que su dependencia tenga valor null. © JMA 2016. All rights reserved 203 Inyectores Explícitos • Habitualmente no tenemos que crear los inyectores en Angular, dado que se crea automáticamente un inyector a nivel del módulo para toda la aplicación durante el proceso de arranque. • Los componentes cuentan con sus propios inyectores. • Se puede crear un inyector de forma explicita: – injector = Injector.create([Http, Logger]); • Para posteriormente obtener instancias inyectadas: – let srv= injector.get(Logger); • Las dependencias son únicas dentro del alcance de un inyector, sin embargo, al ser Angular DI un sistema de inyección jerárquica, los inyectores anidados pueden crear sus propias instancias de servicio. © JMA 2016. All rights reserved 204 58 Jerárquica de inyectores de dependencia • • • • Angular tiene un sistema de inyección de dependencia jerárquica. Hay un árbol de inyectores que se asemeja al árbol de componentes de una aplicación. Se pueden configurar los inyectores en cualquier nivel de ese árbol de componentes. De hecho, no existe el inyector. Una aplicación puede tener múltiples inyectores. Una aplicación angular es un árbol de componentes, cada instancia de componente tiene su propio inyector, que es paralelo al árbol de los inyectores. Cuando un componente solicita una dependencia, Angular intenta satisfácela con un proveedor registrado en el propio inyector de ese componente. Si el componente carece del proveedor, transfiere la solicitud al inyector de su componente anfitrión. Las solicitudes siguen burbujeando hasta que Angular encuentra un inyector que puede manejar la solicitud o llega al módulo. Si se queda sin antepasados y no está registrado en el módulo, Angular genera un error. La anotación @Host() impide el burbujeo y obliga a que el componente anfitrión tenga registrado el proveedor. constructor(@Host() public logger: Logger){} © JMA 2016. All rights reserved 205 Servicios importados • • Un módulo importado que añade proveedores a la aplicación puede ofrecer facilidades para la configuración de dichos proveedores. Por convención, el método estático forRoot de la clase módulo proporciona y configura al mismo tiempo los servicios. Recibe un objeto de configuración de servicio y devuelve un objeto ModuleWithProviders: static forRoot(config: MyServiceConfig): ModuleWithProviders { return { ngModule: CoreModule, providers: [{provide: MyServiceConfig, useValue: config }] }; } • En el servicio: constructor(@Optional() config: MyServiceConfig) { if (config) { … } } • En el módulo principal: imports: [ //… MyCoreModule.forRoot({…}), ], © JMA 2016. All rights reserved 206 59 COMPONENTES © JMA 2016. All rights reserved 207 Modelo de componentes • • • • • • Los componentes encapsulan el contenido (clase), la funcionalidad (clase), la presentación (plantilla) y la estética (css) de un elemento visual. Un componente puede estar compuesto por componentes que a su vez se compongan de otros componentes y así sucesivamente. Sigue un modelo de composición jerárquico con forma de árbol de componentes. La división sucesiva en componentes permite disminuir la complejidad funcional favoreciendo la reutilización y las pruebas. Los componentes establecen un cauce bien definido de entrada/salida para su comunicación con otros componentes. Los componentes son clases: – Decoradas con @Component – Que exponen datos (modelos) y funcionalidad (comandos) para su consumo por la plantilla – Opcionalmente, exponen propiedades (@Input) y eventos (@Output) para interactuar con otros componentes. © JMA 2016. All rights reserved 208 60 Árbol de componentes Aplicación Cabecera Menú Cuerpo Login Inicio Página 1 Tarjetas Tipo 1 Listado Consulta Página 2 Formulario Buscar Ábside Pie Nube Mapa Resultado Tipo 2 © JMA 2016. All rights reserved 209 Componente Clase Modelos Comandos Plantilla @Component HTML Metadatos Servicios Estilo CSS © JMA 2016. All rights reserved 210 61 @Component • selector: Selector CSS (Tag HTML) que indica a Angular que debe crear e instanciar el componente cuando se encuentra un elemento con ese nombre en el HTML. • template: Cadena con el contenido de la plantilla o • templateUrl: La url en la que se encuentra plantilla que se quiere vincular al componente. • styles: Cadena con el contenido del CSS o • styleUrls: Lista de urls a archivos de estilos que se aplican al componente (acepta Less, Sass, Stylus). • entryComponents: Lista de los Componentes/Directivas/Pipes que se insertan dinámicamente en la plantilla del el componente. • providers: Lista de los proveedores disponibles para este componente y sus hijos. © JMA 2016. All rights reserved 211 Componente import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title: string = 'Hola Mundo'; constructor() { } despide(): void { this.title = 'Adios Mundo'; } } © JMA 2016. All rights reserved 213 62 Registrar • Globalmente: import { AppComponent } from './app.component'; @NgModule({ … declarations: [ AppComponent ], … }) export class AppModule { } • En el contenedor: import { HijoComponent } from './hijo.component'; @Component({ … entryComponents: [HijoComponent, …], … }) export class AppComponent { … } © JMA 2016. All rights reserved 214 Propiedades enlazables • • • Externamente se comportan como un atributo público. Internamente están compuesta por dos métodos, get/set que controlan como entra y sale la información. Las propiedades de solo lectura solo disponen del método get. No es obligatorio que tengan un reflejo directo en los atributos de la clase. class EmployeeVM { private _fullName: string; get fullName(): string { return this._fullName; } set fullName(newName: string) { if (this.validate(newName)) { this._fullName = newName; this.fullNameChanged(); } else { // … } } // … } let employee = new EmployeeVM(); employee.fullName = "Bob Smith"; © JMA 2016. All rights reserved 215 63 Atributos del selector • • Los atributos del selector del componente se comportan como los atributos de las etiquetas HTML, permitiendo personalizar y enlazar al componente desde las plantillas. Propiedades de entrada @Input() init: string; • Eventos de salida @Output() updated: EventEmitter = new EventEmitter(); this.updated.emit(value); • Propiedades bidireccionales: Es la combinación de una propiedad de entrada y un evento de salida con el mismo nombre (el evento obligatoriamente con el sufijo Change): @Input() size: number | string; @Output() sizeChange = new EventEmitter(); © JMA 2016. All rights reserved 216 Atributos del selector import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ selector: 'my-sizer', template: `
` }) export class SizerComponent { @Input() size: number | string; @Output() sizeChange = new EventEmitter(); dec() { this.resize(-1); } inc() { this.resize(+1); } resize(delta: number) { this.size = Math.min(40, Math.max(8, +this.size + delta)); this.sizeChange.emit(this.size); } } © JMA 2016. All rights reserved 217 64 Ciclo de vida • Cada componente tiene un ciclo de vida gestionado por el Angular. • Angular lo crea y pinta, crea y pinta sus hijos, comprueba cuando sus propiedades enlazadas a datos cambian, y lo destruye antes de quitarlo del DOM. • Angular ofrece ganchos al ciclo de vida que proporcionan visibilidad a dichos momentos clave y la capacidad de actuar cuando se producen. © JMA 2016. All rights reserved 218 Ciclo de vida Gancho Propósito y temporización ngOnChanges Responder cuando Angular (re) establece las propiedades de entrada enlazadas a datos. ngOnInit Inicializar el componente después de que Angular muestre las primeras propiedades enlazadas a datos y establece las propiedades de entrada del componente. ngDoCheck Llamado cada vez que las propiedades de entrada de un componente o una directiva se comprueban. Lo utilizan para extender la detección de cambios mediante la realización de una comprobación personalizada. ngAfterContentInit Responder después de que Angular proyecta el contenido externo en la vista del componente. ngAfterContentChecked Responder después de que Angular chequee el contenido proyectado en el componente. ngAfterViewInit Responder después de que Angular inicialice las vistas del componente y sus hijos. ngAfterViewChecked Responder después de que Angular chequee las vistas del componente y sus hijos. ngOnDestroy Limpiar justo antes de que Angular destruya el componente. © JMA 2016. All rights reserved 219 65 ESTILOS © JMA 2016. All rights reserved 220 Introducción • Las aplicaciones Angular utilizan CSS estándar para establecer la estética. Angular puede asociar el estilo al componente, lo que permite un diseño más modular que las hojas de estilo regulares. • Para cada componente Angular se puede definir no solo una plantilla HTML, sino también los estilos CSS que acompañan a esa plantilla, especificando los selectores, las reglas y las consultas de medios que se necesite. • Los estilos especificados en los metadatos se aplican solo dentro de la plantilla de ese componente, no son heredados por ningún componente anidado dentro de la plantilla ni por ningún contenido proyectado en el componente. © JMA 2016. All rights reserved 221 66 Modularidad de estilo • Se pueden usar los nombres y selectores de clases de CSS que tengan más sentido en el contexto de cada componente. • Los nombres de clase y los selectores son locales para el componente y no colisionan con las clases y los selectores utilizados en otras partes de la aplicación. • Los cambios en los estilos de otras partes de la aplicación no afectan los estilos del componente. • Se puede ubicar conjuntamente el código CSS de cada componente con el código de TypeScript y HTML del componente, lo que conduce a una estructura de proyecto prolija y ordenada. • Se puede cambiar o eliminar el código CSS del componente sin buscar en toda la aplicación para encontrar dónde se usa el código. © JMA 2016. All rights reserved 222 Selectores especiales • :host selector de pseudoclases para el elemento que aloja al componente. No se puede llegar al elemento host desde el interior del componente con otros selectores porque no forma parte de la propia plantilla del componente dado que está en la plantilla de un componente anfitrión. :host { border: 1px solid black; } :host(.active) { border-width: 3px; } • :host-context() selector que busca una clase CSS en cualquier antecesor del elemento host del componente, hasta la raíz del documento, solo es útil cuando se combina con otro selector para aplicar estilos basados ​en alguna condición externa al componente (si está contenido dentro de un elemento con determinada clase). :host-context(.theme-light) h2 { background-color: #eef; } © JMA 2016. All rights reserved 223 67 Agregar estilos a un componente • Estilos en los metadatos de los componentes • Archivos de estilo en los metadatos de los componentes • Etiqueta ` • Etiqueta en la plantilla (el enlace debe ser relativo a la raíz de la aplicación) template: ` ` • También puede importar archivos CSS en los archivos CSS usando la regla @import del CSS estándar (la URL es relativa al archivo CSS en el que está importando). © JMA 2016. All rights reserved 224 Encapsulación • • Los estilos CSS de los componentes se encapsulan en la vista del componente y no afectan el resto de la aplicación. Para controlar cómo ocurre esta encapsulación por componente se puede establecer el modo de encapsulación en los metadatos del componente: @Component({ styleUrls: ['./app.component.less'], encapsulation: ViewEncapsulation.Native }) • • • Native: la encapsulación de vista utiliza la implementación DOM nativa del sombreado del navegador (Shadow DOM) para adjuntar un DOM sombreado al elemento host del componente, y luego coloca la vista de componente dentro de esa sombra DOM. Los estilos del componente se incluyen dentro del DOM sombreado. (Requiere soporte nativo de los navegadores.) Emulated (por defecto): la encapsulación de vista emula el comportamiento del DOM sombreado mediante el preprocesamiento (y cambio de nombre) del código CSS para aplicar efectivamente el CSS a la vista del componente. None: no se encapsula la vista. Angular agrega el CSS a los estilos globales. Las reglas, aislamientos y protecciones no se aplican. Esto es esencialmente lo mismo que pegar los estilos del componente en el HTML. © JMA 2016. All rights reserved 225 68 Integración con preprocesadores CSS • Si se está utilizando AngularCLI, se pueden escribir archivos de estilo en Sass, Less o Stylus y especificar los archivos en @Component.styleUrls con las extensiones adecuadas (.scss, .less, .styl): @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.less'] }) ... • El proceso de compilación del CLI ejecutará el preprocesador de CSS pertinente. Esto no es posible con los estilos en línea. © JMA 2016. All rights reserved 226 Configuración • Se puede establecer como se generan por defecto los componentes: "schematics": { "@schematics/angular:component": { "inlineTemplate": true, "viewEncapsulation": "Emulated |Native | None" "styleext": "css | less | scss | styl " } }, … "options": { "styles": [ "src/styles.less" ], © JMA 2016. All rights reserved 227 69 PLANTILLAS © JMA 2016. All rights reserved 228 Plantillas • En Angular, las plantillas se escriben en HTML añadiéndole elementos y atributos específicos Angular. • Angular combina la plantilla con la información y funcionalidad de la clase del componente para crear la vista dinámica que el usuario visualiza en el navegador. • Casi toda las etiquetas del body HTML son válidas en las plantillas. La excepción principal es © JMA 2016. All rights reserved 361 JSONP (JSON con Padding) • Si no se importa el módulo HttpClientJsonpModule, las solicitudes de Jsonp llegarán al backend con el método JSONP, donde serán rechazadas. import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable() export class WikipediaService { constructor(private http: HttpClient) {} search (term: string) { let wikiUrl = `http://en.wikipedia.org/w/api.php?search=${term}&action=opensearch&for mat=json`; return this.http.jsonp(wikiUrl, `callback`).subscribe( datos => this.items = datos, error => console.error(`Error: ${error}`) ); } } © JMA 2016. All rights reserved 362 122 Eventos • Los eventos trabajan en un nivel más bajo que las solicitudes. Una sola solicitud puede generar múltiples eventos. • Tipos de eventos: – Sent: La solicitud fue enviada. – ResponseHeader: Se recibieron el código de estado de respuesta y los encabezados. – UploadProgress: Se ha recibido un evento de progreso de subida. – DownloadProgress: Se ha recibido un evento de progreso de descarga. – Response: Se ha recibido la respuesta completa incluyendo el cuerpo. – User: Un evento personalizado de un interceptor o un backend. © JMA 2016. All rights reserved 363 Eventos de progreso • A veces las aplicaciones necesitan transferir grandes cantidades de datos, como por ejemplo subir ficheros, y esas transferencias pueden tomar mucho tiempo. • Es una buena práctica para la experiencia de usuario proporcionar información sobre el progreso de tales transferencias. this.http.post('/upload/file', file, { reportProgress: true, }) .subscribe(event => { if (event.type === HttpEventType.UploadProgress) { const percentDone = Math.round(100 * event.loaded / event.total); console.log(`File is ${percentDone}% uploaded.`); } else if (event instanceof HttpResponse) { console.log('File is completely uploaded!'); } }); © JMA 2016. All rights reserved 364 123 Interceptores • Una característica importante de HttpClient es la interceptación: la capacidad de declarar interceptores que se sitúan entre la aplicación y el backend. • Cuando la aplicación hace una petición, los interceptores la transforman antes de enviarla al servidor. • Los interceptores pueden transformar la respuesta en su camino de regreso antes de que la aplicación la vea. • Esto es útil para múltiples escenarios, desde la autenticación hasta el registro. • Cuando hay varios interceptores en una aplicación, Angular los aplica en el orden en que se registraron. © JMA 2016. All rights reserved 365 Crear un interceptor • Los interceptores son servicios que implementan el interfaz HttpInterceptor, que requiere el método intercept: intercept(req: HttpRequest, next: HttpHandler): Observable> { return next.handle(req); } • next siempre representa el siguiente interceptor en la cadena, si es que existe, o el backend final si no hay más interceptores. • La solicitud es inmutable para asegurar que los interceptores vean la misma petición para cada reintento. Para modificarla es necesario crear una nueva con el método clone(): return next.handle(req.clone({url: req.url.replace('http://', 'https://')})); • Se registran como un servicio múltiple sobre HTTP_INTERCEPTORS en el orden deseado: { provide: HTTP_INTERCEPTORS, useClass: MyInterceptor, multi: true, }, © JMA 2016. All rights reserved 366 124 Modificar la petición import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private auth: AuthService) { } intercept(req: HttpRequest, next: HttpHandler): Observable> { if (!req.withCredentials || ! this.auth.isAutenticated) { return next.handle(req); } const authReq = req.clone({ headers: req.headers.set('Authorization', this.auth.AuthorizationHeader) }); return next.handle(authReq); } } © JMA 2016. All rights reserved 367 Modificar la respuesta import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse } from '@angular/common/http'; import { tap, finalize } from 'rxjs/operators'; @Injectable() export class LoggingInterceptor implements HttpInterceptor { intercept(req: HttpRequest, next: HttpHandler): Observable> { const started = Date.now(); let ok: string; return next.handle(req) .pipe( tap( event => ok = event instanceof HttpResponse ? 'succeeded' : '', error => ok = 'failed' ), finalize(() => { console.log(`${req.method} "${req.urlWithParams}" ${ok} in ${Date.now() - started} ms.`); }) ); } } © JMA 2016. All rights reserved 368 125 Protección ante XSRF • Cross-Site Request Forgery (XSRF) explota la confianza del servidor en la cookie de un usuario. HttpClient soporta el mecanismo “Cookie-to-Header Token” para prevenir ataques XSRF. – El servidor debe establecer un token en una cookie de sesión legible en JavaScript, llamada XSRF-TOKEN, en la carga de la página o en la primera solicitud GET. En las solicitudes posteriores, el cliente debe incluir el encabezado HTTP X-XSRF-TOKEN con el valor recibido en la cookie. – El servidor puede verificar que el valor en la cookie coincida con el del encabezado HTTP y, por lo tanto, asegúrese de que sólo el código que se ejecutó en su dominio pudo haber enviado la solicitud. – El token debe ser único para cada usuario y debe ser verificable por el servidor. Para mayor seguridad se puede incluir el token en un resumen de la cookie de autenticación de su sitio. • Para establecer nombres de cookies / encabezados personalizados: imports: [ // … HttpClientXsrfModule.withConfig({ cookieName: 'My-Xsrf-Cookie', headerName: 'My-Xsrf-Header', }),] • El servicio backend debe configurarse para establecer la cookie y verificar que el encabezado está presente en todas las solicitudes elegibles. © JMA 2016. All rights reserved 369 JWT: JSON Web Tokens https://jwt.io • JSON Web Token (JWT) es un estándar abierto (RFC-7519) basado en JSON para crear un token que sirva para enviar datos entre aplicaciones o servicios y garantizar que sean válidos y seguros. • El caso más común de uso de los JWT es para manejar la autenticación en aplicaciones móviles o web. Para esto cuando el usuario se quiere autenticar manda sus datos de inicio del sesión al servidor, este genera el JWT y se lo manda a la aplicación cliente, posteriormente en cada petición el cliente envía este token que el servidor usa para verificar que el usuario este correctamente autenticado y saber quien es. • Se puede usar con plataformas IDaaS (Identity-as-a-Service) como Auth0 que eliminan la complejidad de la autenticación y su gestión. • También es posible usarlo para transferir cualquier datos entre servicios de nuestra aplicación y asegurarnos de que sean siempre válido. Por ejemplo si tenemos un servicio de envío de email otro servicio podría enviar una petición con un JWT junto al contenido del mail o cualquier otro dato necesario y que estemos seguros que esos datos no fueron alterados de ninguna forma. © JMA 2016. All rights reserved 370 126 AuthService @Injectable({providedIn: 'root'}) export class AuthService { private isAuth = false; private authToken: string = ''; private name = ''; constructor() { if (localStorage && localStorage.AuthService) { const rslt = JSON.parse(localStorage.AuthService); this.isAuth = rslt.isAuth; this.authToken = rslt.authToken; this.name = rslt.name; } } get AuthorizationHeader() { return this.authToken; } get isAutenticated() { return this.isAuth; } get Name() { return this.name; } login(authToken: string, name: string ) { this.isAuth = true; this.authToken = authToken; this.name = name; if (localStorage) { localStorage.AuthService = JSON.stringify({isAuth, authToken, name}); } } logout() { this.isAuth = false; this.authToken = ''; this.name = ''; if (localStorage) { localStorage.removeItem('AuthService'); } } } © JMA 2016. All rights reserved 371 LoginService @Injectable({providedIn: 'root'}) export class LoginService { constructor(private http: HttpClient, private auth: AuthService) { } get isAutenticated() { return this.auth.isAutenticated; } get Name() { return this.auth.Name; } login(usr: string, pwd: string) { return new Observable(observable => this.http.post('http://localhost:4321/login', { name: usr, password: pwd }) .subscribe( data => { if(data['success']) { this.auth.login(data['token'], data['name']); } observable.next(this.auth.isAutenticated); }, (err: HttpErrorResponse) => { observable.error(err); } ) ); } logout() { this.auth.logout(); } } © JMA 2016. All rights reserved 372 127 ENRUTADO © JMA 2016. All rights reserved 375 Introducción • El enrutado permite tener una aplicación de una sola página, pero que es capaz de representar URL distintas, simulando lo que sería una navegación a través páginas web, pero sin salirnos nunca de la página inicial. Esto permite: – Memorizar rutas profundas dentro de nuestra aplicación. Podemos contar con enlaces que nos lleven a partes internas (deeplinks), de modo que no estemos obligados a entrar en la aplicación a través de la pantalla inicial. – Eso facilita también el uso natural del sistema de favoritos (o marcadores) del navegador, así como el historial. Es decir, gracias a las rutas internas, seremos capaces de guardar en favoritos un estado determinado de la aplicación. A través del uso del historial del navegador, para ir hacia delante y atrás en las páginas, podremos navegar entre pantallas de la aplicación con los botones del navegador. – Mantener y cargar módulos en archivos independientes, lo que reduce la carga inicial y permite la carga perezosa. © JMA 2016. All rights reserved 376 128 Rutas internas • • En las URL, la “almohadilla“, el carácter “#“, sirve para hacer rutas a anclas internas: zonas de una página. Cuando se pide al navegador que acceda a una ruta creada con “#“ éste no va a recargar la página (cargando un nuevo documento que pierde el contexto actual), lo que hará es buscar el ancla que corresponda y mover el scroll de la página a ese lugar. – http://example.com/index.html – http://example.com/index. html#/seccion – http://example.com/index. html#/pagina_interna • • • Es importante fijarse en el patrón "#/", sirve para hacer lo que se llaman "enlaces internos" dentro del mismo documento HTML. En el caso de Angular no habrá ningún movimiento de scroll, pues con Javascript se detectará el cambio de ruta en la barra de direcciones para intercambiar la vista que se está mostrando. Los navegadores HTML5 modernos admiten history.pushState, una técnica que cambia la ubicación y el historial de un navegador sin activar una solicitud de página del servidor. El enrutador puede componer una URL "natural" que es indistinguible de una que requeriría una carga de página. © JMA 2016. All rights reserved 377 Hash Bag • Dado que los robots indexadores de contenido de los buscadores no siguen los enlaces al interior de la pagina (que asumen como ya escaneada), el uso del enrutado con # que carga dinámicamente el contenido impide el referenciado en los buscadores. • Para indicarle al robot que debe solicitar el enlace interno se añade una ! después de la # quedando la URL: http://www.example.com/index.html#!ruta © JMA 2016. All rights reserved 378 129 Angular Router • • • El Angular Router ( "router") toma prestado el modelo deeplinks. Puede interpretar una URL del navegador como una instrucción para navegar a una vista generada por el cliente y pasar parámetros opcionales en la ruta al componente para decidir qué contenido específico se quiere manejar. El Angular router es un servicio opcional que presenta la vista de un componente en particular asociado a una determinada URL. No es parte del núcleo Angular. Es un paquete de la biblioteca, @angular/router, a importar en el módulo principal como se haría con cualquier otro modulo Angular. import { RouterModule, Routes } from '@angular/router'; • • La aplicación tendrá un único router. Cuando la URL del navegador cambia, el router busca una correspondencia en la tabla de rutas para determinar el componente que debe mostrar. Las aplicaciones de enrutamiento deben agregar un elemento index.html al principio de la etiqueta para indicar al enrutador cómo componer las URL de navegación. © JMA 2016. All rights reserved 379 Tabla de rutas • • La tabla de ruta es un conjunto de objetos Route. Toda ruta tiene una propiedad path con la ruta que se utiliza como patrón de coincidencia. Puede ser: – – – – • • Única: path: 'mi/ruta/particular' Parametrizada: path: 'mi/ruta/:id' Vacía (solo una vez): path: '' Todas las demás (solo una vez): path: '**' Dado que la búsqueda se realiza secuencialmente la tabla debe estar ordenada de rutas mas especificas a las mas generales. La ruta puede estar asociada a: – Un componente: component: MyComponent – Otra ruta (redirección): redirectTo: '/otra/ruta' – Otro módulo (carga perezosa): loadChildren: 'ruta/otro/modulo' • Adicionalmente se puede indicar: – – – – – outlet: Destino de la ruta. pathMatch: prefix | full children: Subrutas data: datos adicionales Servicios canActivate, canActivateChild, canDeactivate, canLoad © JMA 2016. All rights reserved 380 130 Registrar enrutamiento const routes: Routes = [ { path: '', component: HomeComponent, pathMatch: 'full' }, { path: 'path/:routeParam', component: MyComponent1 }, { path: 'staticPath', component: MyComponent2 }, { path: 'oldPath', redirectTo: '/newPath' }, { path: 'path', component: MyComponent3 , data: { message: 'Custom' } }, { path: '**', component: ErrorComponent }, ]; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(routes) ], // … }) export class AppModule { } © JMA 2016. All rights reserved 381 Directivas • Punto de entrada por defecto: • Punto de entrada con nombre, propiedad outlet de la ruta: • Generador de referencias href: • Nombre de la Class CSS asociada a ruta actual: © JMA 2016. All rights reserved 382 131 Trabajar con rutas • Importar clases: import { Router, ActivatedRoute } from '@angular/router'; • Inyectar dependencias: constructor(private route: ActivatedRoute, private router: Router) { } • Decodificar parámetros y ruta: – Valor actual (Instantánea): let id = this.route.snapshot.params['id']; – Detección de cambios (observable) route.url.map(segments => segments.join('')); let sid = this.route.queryParamMap.pipe(map(p => p.get('sid') || 'None')); this.token = this.route.fragment.pipe(map(f => f || 'None')); • Navegación desde el código: this.router.navigate(['/ruta/nueva/1']); © JMA 2016. All rights reserved 383 Decodifica ruta ngOnInit() { let id = this.route.snapshot.params['id']; if (id) { if (this.route.snapshot.url.slice(-1)[0].path === 'edit') { this.vm.edit(+id); } else { this.vm.view(+id); } } else if (this.route.snapshot.url.slice(-1)[0].path === 'add') { this.vm.add(); } else { this.vm.load(); } } © JMA 2016. All rights reserved 384 132 Parámetros observables private obs$: any; ngOnInit() { this.obs$ = this.route.paramMap.subscribe( (params: ParamMap) => { const id = +params.get('id'); // (+) converts string 'id' to a number if (id) { this.vm.edit(id); } else { this.router.navigate(['/404.html']); } }); } ngOnDestroy() { this.obs$.unsubscribe(); } © JMA 2016. All rights reserved 385 Eventos de ruta Evento Desencadenado NavigationStart cuando comienza la navegación. RoutesRecognized cuando el enrutador analiza la URL y las rutas son reconocidas. RouteConfigLoadStart antes de que empiece la carga perezosa. RouteConfigLoadEnd después de que una ruta se haya cargado de forma perezosa. NavigationEnd cuando la navegación termina exitosamente. NavigationCancel cuando se cancela la navegación: un guardián devuelve falso. NavigationError cuando la navegación falla debido a un error inesperado. • Durante cada navegación, el Router emite eventos de navegación a través de la propiedad observable Router.events a la se le puede agregar suscriptores para tomar decisiones basadas en la secuencia de eventos. this.router.events.subscribe(ev => { if(ev instanceof NavigationEnd) { this.inicio = (ev as NavigationEnd).url == '/'; } }); © JMA 2016. All rights reserved 386 133 Guardianes de rutas • Los guardianes controlan el acceso a las rutas por parte del usuario o si se le permite abandonarla: – CanActivate: verifica el acceso a la ruta. – CanActivateChild: verifica el acceso a las ruta hijas. – CanDeactivate: verifica el abandono de la ruta, permitiendo descartar acciones pendientes que se perderán. – CanLoad: verifica el acceso a un módulo que requiere carga perezosa. • Para crear un guardián hay que crear un servicio que implemente el correspondiente interfaz y registrarlo en cada ruta a controlar. @Injectable() export class AuthGuard implements CanActivate { constructor(private authService: AuthService, private router: Router) {} canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { return this.authService.isAutenticated; } } { path: 'admin', component: AdminComponent, canActivate: [AuthGuard], }, © JMA 2016. All rights reserved 387 Obtener datos antes de navegar • • En algunos casos es interesante resolver el acceso a datos antes de navegar para poder redirigir en caso de no estar disponibles. Servicio: @Injectable({ providedIn: 'root', } ) export class DatosResolve implements Resolve { constructor(private dao: DatosDAOService, private router: Router) {} resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { return this.dao.get(+route.paramMap.get('id')).pipe( take(1), map(data => { if (data) { return data; } else { // id not found this.router.navigate(['/404.html']); return null; } }), catchError(err => { this.router.navigate(['/404.html']); return empty(); }) ); } } © JMA 2016. All rights reserved 388 134 Obtener datos antes de navegar • En la tabla de rutas: { path: 'datos/:id', component: DatosViewComponent, resolve: {elemento: DatosResolve} }, • En el componente: ngOnInit() { this.route.data.subscribe((data: { elemento: any }) => { let e = data.elemento; // … }); © JMA 2016. All rights reserved 389 Mantenimiento de estado • Uno de los posibles aspectos problemáticos del enrutado es que los componentes se instancian con cada vista donde se estén usando, cada vez que se carga la ruta. • Por este motivo todos los datos que se inicializan y se vuelven a poner a sus valores predeterminados cuando carga cualquier la vista. • El mantenimiento de estado consiste en guardar los datos desde que el componente se destruye hasta que se vuelve a crear y se restaura el estado, situación antes de destruirse. • A través de los servicios se puede implementar el mantenimiento de estado de los componentes en caso de ser necesario. – El patrón singleton, utilizado en la inyección de dependencias, asegura que sólo existe una instancia de ellos en el modulo, por lo que no pierden su estado, y, si hay varios componentes que dependen de un mismo servicio, todos recibirán la misma instancia del objeto. © JMA 2016. All rights reserved 390 135 Patrón Composite View © JMA 2016. All rights reserved 391 outlet • Punto de entrada con nombre, propiedad outlet de la ruta: • En la tabla de rutas: { path: 'mypath', component: MyComponent, outlet: 'aside' } • Generador de referencias secundarias: ... • Ruta múltiple: http://example.com/mainpath(aside:mypath) • Navegación desde el código: this.router.navigate([{ outlets: { aside: ['mypath'] } }]); • Eliminar el contenido: this.router.navigate([{ outlets: { aside: null } }]); © JMA 2016. All rights reserved 392 136 Lazy loading • La carga diferida de módulos (lazy loading) se controla con el router: export const routes: Routes = [ // … { path: 'admin', loadChildren: './admin/admin.module#AdminModule' }, ]; • El localizador loadChildren de carga perezosa es una cadena, no un tipo. • La cadena identifica tanto el módulo de archivo (módulo TypeScript) como el módulo de clase (módulo Angular), este último separado del anterior por una #. ./admin/admin.module#AdminModule equivale a una importación en app.module import { AdminModule } from './admin/admin.module'; © JMA 2016. All rights reserved 393 Lazy loading • El módulo LazyLoad no debe estar entre los imports del @NgModule del AppModule. • WebPack crea un bundle por cada módulo enrutado como loadChildren identificado por un número y la sub extensión .chunk – 0.chunk.js, 1.chunk.js, 2.chunk.js, … • El módulo LazyLoad debe tener una tabla de rutas con la ruta vacía que indica el componente inicial del módulo. export const routes: Routes = [ { path: '', component: AdminMainComponent }, { path: 'users', component: UsersComponent }, { path: 'roles', component: RolesComponent }, ]; • La tabla de rutas, en el módulo LazyLoad se debe importar a través del forChild: @NgModule({ imports: [ RouterModule.forChild(routes), // … © JMA 2016. All rights reserved 394 137 DESPLIEGUE © JMA 2016. All rights reserved 395 Pruebas • Son imprescindibles en entornos de calidad: permite ejecutar las pruebas unitarias, las pruebas de extremo a extremo o comprobar la sintaxis. • Para comprobar la sintaxis: Hay que ejecutar el analizador con el comando: – ng lint • Para ejecutar tests unitarios: Se puede lanzar los tests unitarios con karma con el comando: – ng test • Para ejecutar tests e2e: Se puede lanzar los tests end to end con protractor con el comando: – ng e2e © JMA 2016. All rights reserved 396 138 Polyfill • • • Angular se basa en los últimos estándares de la plataforma web. Dirigirse a una gama tan amplia de navegadores es un reto porque no todos son compatibles con todas las funciones de los navegadores modernos. Un Polyfill puede ser un segmento de código o un plugin que permite tener las nuevas funcionalidades u objetos de HTML5 y ES2015 en aquellos navegadores que nativamente no lo soportan. Es necesario activar (des-comentar) en el fichero polyfills.ts las funcionalidades utilizadas. /** IE9, IE10 and IE11 requires all of the following polyfills. **/ import 'core-js/es6/symbol'; import 'core-js/es6/object'; // … import 'core-js/es6/set'; // … • Este archivo incorpora los polyfill obligatorios y muchos opcionales. Algunos polyfill opcionales se tendrá que instalar con npm. © JMA 2016. All rights reserved 397 Compilación • • Una aplicación Angular consiste principalmente en componentes y sus plantillas HTML. Debido a que los componentes y las plantillas proporcionadas por Angular no pueden ser entendidas directamente por el navegador, las aplicaciones de Angular requieren un proceso de compilación antes de que puedan ejecutarse en el navegador. Angular ofrece dos formas de compilar la aplicación: – – • Just-in-Time (JIT), que compila la aplicación en el navegador en tiempo de ejecución (la predeterminada cuando ejecuta los comandos de CLI ng build o ng serve). Ahead-of-Time (AOT), que compila la aplicación antes de que la descargue el navegador. El compilador Ahead-of-Time (AOT) convierte el código TypeScript y el HTML de la aplicación Angular en un eficiente código JavaScript, durante la fase de despliegue antes de que el navegador descargue y ejecute la aplicación. Las ventajas de la compilación AOT son: – – – – – Representación más rápida: Con AOT, el navegador descarga una versión precompilada de la aplicación. El navegador carga directamente el código ejecutable para que pueda procesar la aplicación de inmediato, sin esperar a compilarla primero. Menos peticiones asíncronas: El compilador incluye las plantillas HTML externas y las hojas de estilo CSS dentro de la aplicación JavaScript, eliminando solicitudes ajax separadas para esos archivos de origen. Tamaño de descarga del framework de Angular más pequeño: No es necesario descargar el compilador Angular si la aplicación ya está compilada. El compilador ocupa aproximadamente la mitad de Angular, por lo que omitirlo reduce drásticamente la carga útil de la aplicación. Detectar antes errores de plantillas: El compilador AOT detecta e informa de los errores de enlace de la plantilla durante el proceso de compilación antes de que los usuarios puedan verlos. Mejor seguridad: AOT compila plantillas y componentes HTML en archivos JavaScript mucho antes de que se sirvan al cliente. Sin plantillas para leer y sin el riesgo de evaluación de HTML o JavaScript del lado del cliente, hay menos oportunidades para ataques de inyección. © JMA 2016. All rights reserved 398 139 Despliegue • El despliegue más simple posible 1. 2. 3. • Generar la construcción de producción. Copiar todo dentro de la carpeta de salida (/dist por defecto) a una carpeta en el servidor. Configurar el servidor para redirigir las solicitudes de archivos faltantes a index.html. Construye la aplicación en la carpeta /dist – ng build – ng build --dev • Paso a producción, construye optimizándolo todo para producción – ng build --prod – ng build --prod --env=prod – ng build --target=production --environment=prod • Precompila la aplicación • Cualquier servidor es candidato para desplegar una aplicación Angular. No se necesita un motor del lado del servidor para componer dinámicamente páginas de aplicaciones porque Angular lo hace en el lado del cliente. La aplicaciones Angular Universal y algunas funcionalidades especiales requieren una configuración especial del servidor. – ng build --prod –aot • © JMA 2016. All rights reserved 399 https://angular.io/resources UTILIDADES © JMA 2016. All rights reserved 400 140 Módulos de terceros • Data Libraries – – – – • Angular Fire: The official library for Firebase and Angular Apollo: Apollo is a data stack for modern apps, built with GraphQL. Meteor: Use Angular and Meteor to build full-stack JavaScript apps for Mobile and Desktop. ngrx: Reactive Extensions for angular2 UI Components – – – – – – – – – – – – ag-Grid: A datagrid for Angular with enterprise style features such as sorting, filtering, custom rendering, editing, grouping, aggregation and pivoting. Angular Material 2: Material Design components for Angular Clarity Design System: UX guidelines, HTML/CSS framework, and Angular components working together to craft exceptional experiences Kendo UI: One of the first major UI frameworks to support Angular ng-bootstrap: The Angular version of the Angular UI Bootstrap library. This library is being built from scratch in Typescript using the Bootstrap 4 CSS framework. ng-lightning: Native Angular components & directives for Lightning Design System ng2-bootstrap: Native Angular2 directives for Bootstrap Onsen UI: UI components for hybrid mobile apps with bindings for both Angular 1 & 2. Prime Faces: PrimeNG is a collection of rich UI components for Angular Semantic UI: UI components for Angular using Semantic UI Vaadin: Material design inspired UI components for building great web apps. For mobile and desktop. Wijmo: High-performance UI controls with the most complete Angular support available. © JMA 2016. All rights reserved 401 141

Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
PDF Version                     : 1.7
Linearized                      : No
Page Count                      : 141
Language                        : es-ES
Tagged PDF                      : Yes
XMP Toolkit                     : 3.1-701
Producer                        : Microsoft® PowerPoint® 2019
Title                           : Manual de Angular
Creator                         : Javier
Creator Tool                    : Microsoft® PowerPoint® 2019
Create Date                     : 2019:02:18 08:06:24+01:00
Modify Date                     : 2019:02:18 08:06:24+01:00
Document ID                     : uuid:E004E729-41C8-455E-B26D-8BD37D5CAAB6
Instance ID                     : uuid:E004E729-41C8-455E-B26D-8BD37D5CAAB6
Author                          : Javier
EXIF Metadata provided by EXIF.tools

Navigation menu