Angular 2, ¿se llevará el gato al agua?

En los últimos años es evidente el auge de los frameworks para construir aplicaciones web con el patrón MVC en el lado cliente, es decir, eliminando parte de las responsabilidades en la parte servidora. De esta forma, todo el peso para el renderizado de las vistas y la ejecución de la lógica recae sobre los navegadores. Os recomiendo este excelente artículo de arquitecturajava en el que podéis profundizar más sobre este tema.

En este contexto, Google lanzó durante 2016 la primera versión estable de Angular 2, que ha sorprendido a todos introduciendo cambios importantes respecto a su primera versión:

  • La decisión más sorprendente ha sido la de introducir TypeScript como lenguaje de desarrollo de la plataforma, lenguaje creado por Microsoft. Se puede seguir usando Javascript aunque la comunidad de desarrolladores deberá aprender un nuevo lenguaje para aprovechar toda la potencia del framework. Este lenguaje requerirá de una compilación previa como Java y .NET, al contrario que Javascript que es interpretado.
  • Para el manejo de promesas se apoya en la librería de RxJs. Esto es algo nuevo que los desarrolladores deberán aprender, bien porque no conozcan el paradigma de programación basado en promesas o bien porque aunque lo conozcan, en la versión anterior se utilizaba la librería $q.
  • Orientado a componentes y no a controladores.
  • Para crear un proyecto dummy se genera gran cantidad de ficheros, hecho que antes no ocurría con la primera versión.
  • La velocidad de los cambios está siendo meteórica hablándose ya de Angular 4 cuando apenas hace unos meses se hablaba de Angular 2 y Angular 2.2.

 

Arquitectura de Angular

Para explicar brevemente la arquitectura de Angular nos apoyamos en la imagen extraída de su documentación oficial.

Arquitectura de Angular

Arquitectura de Angular

Para escribir nuestras vistas o templates utilizaremos el lenguaje de marcas de Angular. Mediante directivas, tanto estructurales (nfIg, ngFor) como de tipo atributo (ngModel) el framework extiende el lenguaje HTML para añadir comportamiento a los elementos del DOM. Con el ngIf, por ejemplo, podemos controlar que un elemento del DOM se muestre o no de acuerdo a una determinada expresión. Con la directiva ngModel podemos asociar un campo de texto a un valor determinado (data binding). Esta asociación puede ser unidireccional,  de modo que el valor solo se muestra en el campo desde el modelo pero no se podrá modificar, como bidireccional, de tal forma que cualquier modificación en la vista provoca cambios en el modelo y viceversa. El código de estas vistas normalmente se definirá en ficheros HTML aunque también puede estar embebido en un componente.

Cada una de las vistas estará respaldada por un componente, en el que definiremos la información que mostraremos en las vistas o funciones que respondan a los eventos provocados por los usuarios.

La lógica de negocio deberá estar encapsulada mediante servicios como buena práctica para separar las responsabilidades entre capas. De esta forma seguiremos desarrollando nuestras aplicaciones con el patrón MVC. Contaremos con la inyección de dependencias, concepto propio de lenguajes de servidor. Podremos inyectar nuestros servicios en los componentes con una anotación como en Spring (@Inject); personalmente me parece una idea estupenda para ser aceptado por un mayor número de la comunidad de desarrolladores.

Tanto los servicios como los componentes son clases, aunque los componentes irán anotados mediante la anotación @Component con una serie de metadatos para asociarle el comportamiento. Para escribir las clases podremos utilizar el lenguaje Typescript que nos proporciona la inyección de dependencias, las anotaciones y la modularización.

Por último, toda aplicación de Angular cuenta con un módulo raíz, que pasaremos a su sistema de arranque (system.js). Una vez hecho esto, el framework controlará nuestra aplicación mostrando el contenido que hayamos definido y respondiendo a las interacciones de los usuarios.

 

Módulos

Las aplicaciones de Angular son modulares. La sintaxis para definir módulos se basa en la nueva versión de Javascript ECMA Script 2015 o ES6. Dicha especificación cuenta con elementos típicos de los lenguajes OO como clases y herencia, el uso de módulos o las funciones arrow. ¿Qué problema tenemos actualmente? Pues que los navegadores actuales no soportan la mayoría de características del nuevo Javascript. ¿La tendrán próximamente? Esperemos que sí !!.

Un módulo es un conjunto de código destinado a cumplir una función, pudiendo exportar los elementos más relevantes como una Clase que se encargue por ejemplo de realizar peticiones HTTP.

En Angular 2 existen módulos que son librerías de conjuntos de otros módulos. El core del framework está empaquetado como un conjunto de librerías asociadas a paquetes npm.

Las librerías más importantes son:

  • @angular/core. Clases, Componentes, Modulos…
  • @angular/common. Utilidades comunes.
  • @angular/router. Enrutador para nuestras aplicaciones (controlador)
  • @angular/http. Realizar peticiones HTTP como por ejemplo llamadas a web services.

 

Componentes

Un componente se escribe pensando en una sección de nuestras páginas. Podría ser la cabecera, una barra de navegación, el pie de página, un menú, el contenido principal de la página… Cada componente se asocia a una vista, bien mediante un archivo html separado o embebido en el propio componente.

Aquí vamos a definir todas las propiedades y métodos que utilizamos en nuestras vistas. Ejemplo de lo que podremos definir aquí es una lista de objetos persona. Lo que no deberemos definir es código que debería estar en servicios, como por ejemplo, un método que recupera la información de una persona llamando a un servicio REST.

Podremos definir propiedades directamente en el código o bien declararlas como private en el constructor, método porque el que la definimos y la inicializamos directamente.

Además existen métodos especiales pertenecientes al ciclo de vida de Angular 2 en el que podremos introducir nuestro código. Por ejemplo, el método ngOnInit se ejecuta después de llamar al constructor y al método ngOnChanges. Podéis ver el ciclo de vida de Angular 2 aquí.

Os muestro un ejemplo de componente:

 

Templates

Los templates los vamos a utilizar para definir las vistas de nuestra aplicación. Además de usar HTML usaremos otros componentes, directivas y expresiones de data binding.

Uso de otros componentes

A continuación vemos como definir el layout del componente principal de la aplicación definiendo otros subcomponentes. App-header, app-body, y app-footer serán otros de nuestros componentes en la aplicación.

 

Directivas estructurales y data binding

Como el movimiento se demuestra andando, en el siguiente ejemplo podemos ver algunas directivas estructurales y expresiones de data binding.

(click). Con esta directiva definimos una función para el tratamiento del evento click del botón.

*ngIf. Mostramos el elemento div si la expresión mostrar definida en el componente es true.

{{texto}}. Mediante la interpolación podemos mostrar propiedades definidas en los componentes. Los datos no se modifican en el componente, son de sólo lectura.

Otro ejemplo que considero interesante es ver como definir un campo de formulario con un doble binding, es decir, los cambios en la vista afectan al modelo y los cambios en el modelo afectan a la vista de inmediato. Esto se basa en el patrón MVVM, evolución del patrón MVC creada por Martin Fowler.

[(ngModel)]=”usuario.nombre”, asignamos la propiedad usuario.nombre definida en el componente al campo nombre de este formulario. Si el usuario introduce un nuevo valor en su nombre se verá reflejado en el modelo y viceversa.

Metadatos

Con los metadatos podemos indicar por ejemplo que una simple Javascript es un componente. Para verlo os muestro un ejemplo:

El significado de cada metadato es el siguiente:

  • selector. Cuando Angular se encuentra con el nombre que aparece en este metadato creará una instancia del componente.
  • moduleId. Asignando el valor module.id Angular busca los templates asociados en la ruta relativa donde se encuentra el componente y no mediante rutas absolutas.
  • templateUrl. La url donde se encuentra el template asociado al componente.
  • styleUrls. Array de ficheros CSS que contienen estilos que se aplicarán solo a nuestro componente.
  • directives. Array de los componentes y las directivas que usaremos en nuestro componente.
  • provides. Aquí definimos los servicios de los que depende nuestro componente.

Angular es mucho más que esto pero creo que para ir abriendo boca y engancharos al framework de moda no está nada mal. Nos dejamos por el camino las pipes, las promesas pero estoy seguro que vais a investigar por vuestra cuenta…

En un próximo post veremos algunas herramientas como un IDE para trabajar con Angular y como crear proyectos desde 0. Espero que os haya interesado.

Un saludo.