1. AngularJS
1.1. ¿Qué es AngularJS?
AngularJS es un framework de JavaScript de código abierto, mantenido por Google, que ayuda con la gestión de lo que se conoce como aplicaciones de una sola página (en inglés, single-page applications). Su objetivo es aumentar las aplicaciones basadas en navegador con (MVC) Capacidad de Modelo Vista Controlador, en un esfuerzo para hacer que el desarrollo y las pruebas más fáciles.
1.1.1. ¿Single-page web applications?
Una single-page web application (en adelante SPA), es una aplicación web que se ejecuta completamente en una única página web, con el objetivo de proporcionar una experiencia más fluida y similar a la que nos encontraríamos en una aplicación de escritorio
En una aplicación SPA, todos los datos necesarios, como el HTML, CSS o JavaScript, se cargan y añaden en la página cuando es necesario, normalmente respondiendo a acciones del usuario. En ningún momento del proceso veremos una recarga total de la página. Para esto, como os imaginaréis a lo largo del proceso de ejecución de una aplicación SPA existe una comunicación con el servidor en segundo plano.
Ejemplos de aplcaciones SPA
-
GMail
-
Google+
-
Facebook
-
Twitter
-
App de YouTube de PS3, que además está realizada con AngularJS
1.2. Volviendo a AngularJS…
Volviendo a AngularJS y a sus características principales. AngularJS es un framework para escribir aplicaciones en JavaScript. Es prescriptivo, ya que existe una manera recomendada de hacer las cosas con él. Además, tiene su propia vuelta de tuerca del omnipresente patrón MVC, especialmente adaptado a JavaScript y al desarrollo de aplicaciones SPA.

1.3. Principales características de AngularJS
A continuación, vamos a ver alogos de los aspectos más importantes de AngularJS. Puede que ahora se mencionen otros conceptos, que en su momento quedarán aclarados.
1.3.1. Two-way data binding
Según Martin Fowler[1], este patrón consiste en: Un mecanismo que garantiza que cualquier cambio realizado sobre los datos en un control de la interfaz, se traslada inmediatamente al estado de la sesión (y viceversa).
En una aplicaciónAngularJS el two-way data binding consiste en la sincronización automática entre los componentes del modelo y de la vista. La vista es una proyección del modelo en todo momento. Cuando realizamos un cambio sobre el modelo éste se refleja inmediatamente sobre la vista. image::img/ses01/02.png[width="66%"]
En AngularJS, este mecanismo funciona de la siguiente manera: una plantilla (que es código HTML) se compila en el navegador. Esta compilación hace que cualquier cambio en el modelo se refleje inmediatamente en la vista. También hará que todo cambio que realicemos en la vista se propage al modelo. El modelo es la single-source-of-truth del estado de la aplicación, lo que simplifica mucho las cosas, al no tener que gestionar más que el modelo, y pensar el la vista como una proyección de éste.
Dado que la vista es una proyección del modelo, el controlador queda totalmente separado de la vista y no es consciente de ella. De esta manera, realizar tests sobre un controlador es mucho más sencillo, ya que no depende de la vista ni de ningún elemento del DOM.
Imaginémonos que queremos implementar esta funcionalidad en JavaScript plano, o con jQuery. Tendríamos que hacer un número enorme de consultas al DOM para mantener esta funcionalidad, y hacer que se ejecute periódicamente para que los datos siempre se encuentren actualizados. Sin embargo, AngularJS ya realiza este trabajo por nosotros, y el data binding se realiza de manera transparente.
Así, para una pantalla que muestre el nombre de usuario, sería tan sencillo como declarar una variable con el nombre de usuario en nuestro código JavaScript:
1 var name = 'Alex';
En nuestra vista, utilizaremos la notación {{ }}, que nos pemite ligar expresiones a elementos:
1 <h1>Bienvenido, {{ name }}</h1>
1.3.2. MVW (Model-View-Whatever)
Esto es lo que piensa Igor Minar, lead de AngularJS, cuando se entra en cuestiones sobre qué patrón sigue el framework.
MVC vs MVVM vs MVP. Un asunto controvertido en el que muchos desarrolladores pueden pasarse horas y horas discutiendo. Durante muchos años, AngularJS estaba más cerca del MVC que de cualquier otra cosa. Sin embargo, a medida que pasó el tiempo y debifo a una serie de refactorings y mejoras en la API, ahora está más cerca de MVVM, donde el objeto $scope puede considerarse como un ViewModel que podemos decorar con una función que llamamos Controlador. Ser capaces de categorizar un framework como un MV* tiene sus ventajas. Ayuda a los desarrolladores a estar más cómodos con sus APIS, haciendo más fácil crear un modelo mental que representa la aplicación que están construyendo con el framework. También, ayuda a establecer cierta terminología a emplear por los desarrolladores. Una vez dicho esto, veo muchos desarrolladores que construyen aplicaciones alucinantes, muy bien diseñadas, que siguen los principios de separation of concerns; y muy pocos que pierden el tiempo discutiendo chorradas dobre MV*. Y por esta razón, por la presente declaro que AngularJS es un framework MVW (Model-View-Whatever). Donde whatever es whatever works for you. Angular proporciona mucha flexibilidad para separar de manera sencilla la lógica de presentación de la de diseño y el estado de presentación. Por favor, úsalo para incrementar tu productividad y mantenibilidad de tu aplicación, y no para discutir sobre cosas que, en el fondo, no importan tanto.
https://plus.google.com/+AngularJS/posts/aZNVhj355G2
A efectos prácticos, y como se dice en la cita, el patrón Model View ViewModel (MVVM) es una aproximación bastante cercana para describir de manera general el comportamiento de AngularJS.
El patrón MVVM funciona muy bien en aplicaciones con interfaces de usuario ricas, ya que la Vista se vincula al ViewModel y, cuando el estado del ViewModel cambia, la Vista se actualiza automáticamente gracias, precisamente, al two-way-databinding. En AngularJS, una Vista es simplemente código HTML compilado con elementos propios del framework. Una vez finaliza el ciclo de compilación, la Vista se vincula al objeto $scope, que es el ViewModel. Ya veremos en profundidad el objeto $scope, pero adelantamos que es un objeto JavaScript que captura ciertos eventos para permitir el data binding. También, podemos exponer funciones al ViewModel para poder ejecutar funciones.
image::img/ses01/003_mvvm.png
Ya veremos esto más adelante, y veremos lo sencillo que es trabajar con este patrón, que crea una separación muy clara entre la Vista y la lógica que la conduce. Uno de los "efectos secundarios" del patrón ViewModel, es que permite que el código sea muy testable.
1.3.3. Plantillas HTML
Otra de las grandes características de AngularJS es el uso de HTML para la creación de plantillas. Éstas pueden ser útiles cuando queremos predefinir un layout con secciones dinámicas está conectado con una estructura de datos. Por ejemplo, para repetir un mismo elemento DOM en una página, como una lista o una tabla. Podríamos definir cómo queremos que se vea una fila, y después asociarle una estructura de datos, como un array de JavaScript. Esta plantilla se repetiría tantas veces como ítems encontremos en el array, asociando el ítem al contenido.
Hay muchas librerías de templating, y muy buenas. Pero para la mayoría de ellas se requiere aprender una nueva sintaxis. Esta complejidad adicional puede ralentizar al desarrollador. Además, muchas suelen pasar por un preprocesador.
El navegador evalúa las plantillas de AngularJS como el resto de HTML de la página. Hay cierta funcionalidad de AngularJS que gestiona cómo se representan los datos, que veremos cómo funciona en las próximas sesiones.
1.3.4. Deep linking
Como hemos comoentado, AngularJS es un framework para construir aplicaciones SPA. Sin embargo, es posible que nuestros usuarios no se den cuenta de este detalle. En muchas aplicaciones SPA modernas, está prohibido usar el back button ya que no se tiene en cuenta a la hora de programar. Sin embargo, AngularJS hace uso de la API de history de HTML5. ¿Que tu navegador no implementa esa API? Es igual, AngularJS seguirá gestionando bien el histórico gracias al control de cambios en el hashbang.
Para un usuario, esto significa que se pueden guardar y compartir cualquier estado de la apliación, cosa muy importante hoy en día debido al social media. También nos permite a los desarrolladores cambiar el estado de la aplicación de la manera más sencilla posible: mediante el uso de hipervínculos.
1.3.5. Inyección de dependencias
La inyección de dependencias (DI por sus siglas en inglés) describe una técnica que hemos estado usando toda la vida. Si alguna vez has usado una función que acepta un parámetro, ya has hecho uso de la inyección de dependencias. Inyectas algo de lo que depende tu función para realizar su trabajo. Nada más y nada menos.
image::img/ses01/004_di.png
Al modularizar tu código con elementos inyectables, éste es más fácil de testear, ya que en cualquier momento puedes reemplazar uno de los elementos por otro, siempre y cuando implemente la misma interfaz.
Veamos un sencillo caso de inyección de dependencias. El siguiente código no hace uso de ellas:
1
2
3
4
5
6
7 function a () {
return 5;
}
function b () {
return a() + 1;
}
console.log(b());
Con un código tan pequeño y tan simple, ya se plantean dos problemas:
-
Orden: necesariamente, la función a debe cargarse antes que b. Si están en ficheros separados, hay que tener esto en cuenta. ¿Qué pasa cuando nuestra aplicación crece más y más? Nuestra aplicación se hace dependiente del orden.
-
Testabilidad: Se hace imposible sustituir a por un objeto mock para poder testarlo.
Si usáramos DI, nuestro código tendría un aspecto similar al siguiente:
1
2
3
4
5
6
7
8
9 service('a', function () {
return 5;
});
service('b', function (a) {
return a() + 5;
});
service('main', function (b) {
console.log(b());
});
Este cambio tiene varias ventajas: por una parte, ya no dependemos del orden, y nuestro código no tiene que seguir una secuencia. estp implica que, podemos extraer cualquiera de los bloques a otro fichero, lo que en aplicaciones grandes será más que conveniente. Además, en cualquier momento podemos sobreescribir cualquiera de las funciones, cosa muy importante para realizar tests.
1.3.6. Directivas
Las directivas son la parte más interesante de AngularJS, ya que nos permiten extender HTML para que realice todo lo que nosotros queramos.
Podemos crear elementos del DOM personalizados, atributos o clases que incorporan cierta funcionalidad definida en JavaScript. Aunque HTML es excelente para definir un layout, para el resto se queda corto. Las directivas nos proporcionan un mecanismo para unir la naturaleza declarativa de HTML con la naturaleza funcional de JavaScript en un mismo elemento. Así, cuando aprendamos a utilizar directivas, en lugar de pintar un modal de bootstrap de esta manera:
1
2
3
4
5
6
7
8
9
10
11 <div class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Esto sería un modal con bootstrap y jQuery</h4>
</div>
<div class="modal-body">He aquí el contenido del modal</div>
</div>
</div>
</div>
Lo haremos de esta otra:
1 <modal title="Esto sería un modal con AngularJS">He aquí el contenido del modal. Fácil, ¿no?</modal>
Para los curiosos, podéis ir jugando con el código de este modal en http://jsfiddle.net/alexsuch/RLQhh/.
1.4. Ventajas e inconvenientes de AngularJS
Se ha escrito mucho acerca de las ventajas e inconvenientes de este framework. En este apartado hacemos una recopilación de los elementos más destacados y odiados por la comunidad.
1.4.1. Ventajas
-
Es comprensivo. Se trata de un framework con una curva de aprendizaje poco elevada, lo que nos permite estar desarrollando aplicaciones sencillas en poco tiempo. No necesitamos conocer a fondo los conceptos de módule, service, factory, scope, inyección de dependencias o directive. ¡Con saber hacer un controlador y las directivas que proporciona el sistema ya podemos echar a correr!.
-
Trabajamos con POJSOS (Plain Old Javascript Objects). Se puede, y se recomienda, el uso de primitivas y objetos Javascript como Arrays, Dates, y objetos todo lo complejos que queramos para trabajar con AngularJS.
-
Inyección de depenedencias. Como hemos visto, la inyección de dependencias nos permite desacoplar nuestro código, y hacerlo más testable.
-
Las plantillas pueden escribirse en HTML. AngularJS es muy bueno para la construcción de single page applications, y eso se nota en la facilidad para la creación de plantillas. A diferencia de otros frameworks, donde las plantillas se definen en variables o con una sintaxis específica, en AngularJS podemos definir plantillas utilizando exclusivamente HTML y documentos HTML, que podemos extender o no mediante directivas.
-
Muy buena integración del framework con REST y AJAX. De manera que con muy pocas líneas de código podemos realizar una petición al servidor, obtener y procesar los datos, y mostrar la información que necesitamos en nuestra vista.
-
Integración con jQuery. AngularJS trabaja de base con un subset de jQuery, llamado jqLite, que permite la manipulación del DOM de manera compatible en todos los navegadores. Todas las referencias a elementos de angular están envueltos con jqLite. Sin embargo, si añadimos jQuery a nuestro proyecto, el framework lo detecta y hace uso de éste en lugar de jQuery.
-
Modularidad. Se pueden elaborar de manera sencilla componentes que podremos reutilizar en posteriores desarrollos.
-
Minificación. La Minificación tiene un doble objetivo: por un lado, conseguir que nuestra aplicación “pese” menos; por otro, se pretende ofuscar de alguna manera el código para hacer un poco más segura nuestra aplicación. AngularJS tiene en cuenta esto, y nos permite minificar nuestra aplicación de manera sencilla y con pocos cambios, en caso de no haberlo previsto inicialmente.
1.4.2. Inconvenientes
-
Al igual que hemos dicho que la curva de aprendizaje inicial es muy baja, cuando queremos hacer algo avanzado en aplicaciones más serias, la cosa puede resultar un poco difícil debido a la falta de documentación, o documentación errónea en algunos casos. Afortunadamente, el equipo de AngularJS está trabajando a diario en esto, y entre esto y la cada vez más creciente comunidad de usuarios, este problema se va minificando a la carrera.
-
El framework de validación de formularios no es del todo perfecto, y de vez en cuando hay que hacer algunos trucos para que haga lo que nosotros queremos.
-
Como pasa con todos los frameworks, ninguno es la panacea y encontraremos escenarios donde AngularJS no encaje.
1.5. Recursos online
AngularJS tiene una comunidad de desarrolladores cada vez más extensa. Algu nos de los canales que podemos utilizar para discutir sobre cualquier elemento del framework o pedir ayuda son:
-
Lista de correo en angular@googlegroups.com
-
Comunidad de Google+ https://plus.google.com/u/0/communities/115368820700870330756
-
Canal de IRC #angularjs
-
Tag *angularjs* en http://stackoverflow.com
-
Twitter @angularjs
-
http://builtwith.angularjs.org/ nos proporciona un listado de grandes aplicaciones realizadas con AngularJS
Además, tenemos diversos sitios donde poder seguir con el aprendizaje de AngularJS, como pueden ser:
-
Página oficial de AngularJS (http://www.angularjs.org). Donde tenemos un poco de todo: videotutoriales, referencia de la API, posibilidad de descargarnos el código fuente, etc. Un must have en nuestros marcadores del navegador.
-
Blog de AngularJS: http://blog.angularjs.org
-
Canal de youtube de AngularJS (http://www.youtube.com/user/angularjs) donde hay charlas, tutoriales y una variedad muy extensa de vídeos.
-
http://egghead.io/. Otro must have, y probablemente uno de los mejores sitios de videotutoriales de AngularJS
-
Blog de Alejandro Such (http://veamospues.wordpress.com). Escribe poco, pero cuando lo hace es muy interesante ;)
También, hacer especial mención a la web http://ngmodules.org/. En ella encontramos una base de datos con un extenso repertorio de módulos hechos por la comunidad y que pueden servirnos en muchos de nuestros proyectos. Encontramos módulos tan usados como angular-ui o angulartics. Cómo no, siempre es recomendable pasarse de vez en cuando por github a ver si hay proyectos similares a módulos que podamos necesitar.