0% encontró este documento útil (0 votos)
295 vistas97 páginas

Arquitecturas Web Con Angular - Js

Este documento introduce Angular.js como alternativa a jQuery para construir aplicaciones web. Explica cómo jQuery puede generar problemas al centralizar demasiadas responsabilidades, mientras que Angular.js se enfoca en dividir responsabilidades. Luego muestra un ejemplo básico de cómo construir la misma aplicación de facturas usando Angular.js en lugar de jQuery, dividiendo responsabilidades entre el modelo, la vista y el controlador.

Cargado por

joshua
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
295 vistas97 páginas

Arquitecturas Web Con Angular - Js

Este documento introduce Angular.js como alternativa a jQuery para construir aplicaciones web. Explica cómo jQuery puede generar problemas al centralizar demasiadas responsabilidades, mientras que Angular.js se enfoca en dividir responsabilidades. Luego muestra un ejemplo básico de cómo construir la misma aplicación de facturas usando Angular.js en lugar de jQuery, dividiendo responsabilidades entre el modelo, la vista y el controlador.

Cargado por

joshua
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 97

ARQUITECTURAS WEB CON ANGULAR.

JS

!
PGINA "1 DE "97

WWWW.ARQUITECTURAJAVA.COM

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Autor
!

Cecilio lvarez Caules es Oracle Enterprise Architect, Sun


Certified Business Component Developer, Sun Certified Web
Component Developer y Sun Certified Java Programmer. Es
adems Microsoft Certified Solution Developer, Microsoft
Certified Enterprise Developer y Microsoft Certified Trainer.
Trabaja como Arquitecto, Consultor y Trainer desde hace ms de
15 aos para distintas empresas del sector.

Puedes seguirme a travs de las siguientes redes

LinkedIn
https://www.linkedin.com/profile/view?id=2949192&trk=tab_pro
Twitter
https://twitter.com/arquitectojava

Prologo
Este es el tercer libro que escribo sobre Arquitecturas y buenas prcticas . Los dos
primeros fueron :

Arquitectura Java Slida descargable desde http://www.arquitecturajava.com


sin coste alguno
Arquitectura Java JPA Domain Driven Design ( editado en formato kindle)

PGINA "2 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Este tercer libro est orientado a Arquitecturas Web y concretamente a aprender a


manejar y perder el miedo a uno de los framework JavaScript Web que estn ms
de moda: Angular.js

Espero que el libro sirva de introduccin y ayude a solventar las dudas sobre este
framework tan interesante.

Agradecimientos
Quiero aprovechar a agradecer a mi pareja y mi editora Olga Pelaez Tapia la
paciencia que ha tenido al revisar un documento tan tcnico. Por otro lado quiero
agradecer tambin a Ral Arabaolaza que me pusiera al tanto de la existencia de
este framework hace ya ms de un ao y lo interesante que era comenzar a trabajar
con l.

PGINA "3 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Introduccin, Angular.js vs
jQuery
Angular.js es un framework Javascript relativamente nuevo y no es fcil manejarlo
en un principio. Vamos a comenzar como siempre desde cero. Para ello
construiremos, como punto de partida, un ejemplo utilizando jQuery para despus
ir evolucionando paso a paso hacia el mundo de Angular.js. As pues, debemos
descargar la ltima versin de jQuery de su pgina web:

http://www.jquery.com

!
jQuery y Facturas
!

Vamos a trabajar con el concepto de Factura (id,concepto,importe) y,


utilizando jQuery, procederemos a imprimir las diferentes propiedades por
pantalla. Para ello usaremos el siguiente cdigo:

<html>
<head>
<script type="text/javascript" src="jquery-1.11.1.js">
</script>
<script type=text/javascript">

!
$(document).ready(function() {
!
var factura= {"id":1,"concepto":"mac","importe":1000};
!
$("p:eq(0)").text(factura.id);
$("p:eq(1)").text(factura.concepto);
$("p:eq(2)").text(factura.importe);

PGINA "4 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

});

</script>
</head>
<body>
<p><p>
<p></p>
<p></p>
</body>
</html>

!
En primer lugar, hemos construido una Factura como un objeto de Javascript:
!
var factura= {"id":1,"concepto":"mac","importe":1000};

Despus hemos utilizado selector de prrafo p ms el selector de posicin eq


de jQuery para ir dibujando las diferentes propiedades de la Factura en el primer,
segundo y tercer prrafo:

$("p:eq(0)").text(factura.id);
$("p:eq(1)").text(factura.concepto);
$("p:eq(2)").text(factura.importe);

De esta forma, jQuery nos imprime el contenido de la Factura

!
!

PGINA "5 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

No hay mucho ms que resear, el cdigo funciona correctamente y simplifica


significativamente el uso puro de Javascript y DOM que tendramos que haber
usado para realizar la misma operacin.

!
Aadir Botones
!

Vamos a realizar algunos cambios que en principio nos parecen poco relevantes, de
tal forma que tengamos diferentes botones para cambiar cada una de las distintas
propiedades de la Factura.

<p>
<input type="button" id="botonId" value="cambiarID"/>
</p>
<p>
<input type="button" id="botonConcepto" value="cambiarConcepto"/>
</p>
<p>
<input type="button" id="botonImporte" value=cambiarImporte"/>
</p>

El resultado ser el siguiente :

!
PGINA "6 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
No hemos hecho nada drstico. Ahora aadiremos cdigo a nuestro ejemplo para
que cada botn responda de forma correcta al evento de click:

!
!
$("#botonId").click(function() {
!

factura.id=2;
$("p:eq(0)").text(factura.id);

!
})
!
$("#botonConcepto").click(function() {
!
factura.concepto="iphone"
$("p:eq(1)").text(factura.concepto);

!
});
!
$("#botonImporte").click(function() {
!

factura.importe=700;
$("p:eq(2)").text(factura.importe);

!
});
!

Si pulsamos cada uno de los botones, estaremos cambiando tanto los datos que la
Factura almacena como los datos que se presentan en los prrafos utilizando el
mtodo .text() de jQuery.

PGINA "7 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Problemas con JQuery

Todo parece normal en el cdigo, pero si lo analizamos un poco ms


detalladamente, nos podemos dar cuenta de que resulta repetitivo cambiar las
propiedades del objeto y a continuacin cambiar al mismo tiempo el contenido del
prrafo:

!
factura.importe=700;
!

$("p:eq(2)").text(factura.importe);

Con jQuery nos estamos viendo obligados a cambiar tanto el objeto como la capa
de presentacin (prrafos) de la pgina.

!
PGINA "8 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Estamos trabajando el doble. Quiere decir esto que JQuery est mal
diseado?. La respuesta es NO. jQuery es un framework que est orientado a
gestionar la capa de presentacin y es algo que hace de forma correcta,
simplificando claramente el trabajo con ella. Sin embargo, no es capaz de cubrir
otro tipo de problemas como con el que nos encontramos ahora.

!
Asignacin de Responsabilidades
!

En estos momentos tenemos un problema serio de asignacin de responsabilidades


pero no es fcil de detectar. Vamos a poner un ejemplo similar basado en la vida
cotidiana. Imaginemos una cafetera donde hay un encargado que pone precio a
los cafs que vendemos.

Resulta que el negocio nos ha ido bien y hemos abierto otras 3 cafeteras. As que
cuando nuestro encargado cambie el precio del caf, deber ir a cada una de las
cafeteras y cambiar el precio en ellas tambin.

!
!
!
!
!
!
!
!

PGINA "9 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
!
Ahora bien Qu suceder cuando el nmero de cafeteras o el nmero de
productos aumente?. Nuestro encargado no podr asumir de forma eficiente el
cambio de los precios de todos los productos.

!
!
!
!

PGINA "10 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Divisin de Responsabilidades

Es fcil ver que nuestro Encargado esta asumiendo demasiadas responsabilidades y


no puede realizar todas de una forma eficaz. Cul puede ser una solucin
razonable y escalable? . En este caso podemos dividir las responsabilidades y
contratar un encargado en cada una de las cafeteras de tal forma que sean estos
encargados los que cambien los precios en cada una de ellas, basndose en los
precios que les transmite el Encargado principal.

PGINA "11 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Este es un ejemplo elemental de uno de los patrones ms conocidos: El patrn
observador/observable ya que cada uno de los empleados de las cafeteras
observan los cambios que realiza el encargado principal.

jQuery y Responsabilidad

PGINA "12 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

En el ejemplo que acabamos de construir con JQuery estamos ante un problema


de divisin de responsabilidades ya que jQuery se encarga de todo y tenemos las
responsabilidades demasiado centralizadas. Esto finalmente genera ms trabajo

Angular.js y Responsabilidades

Angular.js es un Framework de Javascript que est enfocado hacia la divisin de


responsabilidades. Vamos a ir introducindolo paulatinamente en los siguientes
captulos.

PGINA "13 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Introduccin a Angular.js
Acabamos de ver los problemas que tiene trabajar con un framework como jQuery
en cuanto a la evolucin de la aplicacin se refiere. Es hora de introducir Angular.js
como alternativa. Para ello, lo primero que haremos ser descargarnos de su
pgina web la ltima versin de angular :

https://www.angularjs.org/

Descargado el framework, vamos a crear el mismo ejemplo de jQuery con


Angular.js :

<html ng-app>
<head>
<script type="text/javascript" src="angular.min.js">
</script>
<script type="text/javascript">

!
function controladorFactura($scope) {
!
$scope.factura = {"id":1,"concepto":"mac","importe":1000};
!
}

</script>
</head>
<body ng-controller="controladorFactura">
<p>{{factura.id}}</p>
<p>{{factura.concepto}}</p>
<p>{{factura.importe}}</p>

</body>
</html>
PGINA "14 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
En un principio parece incomprensible, es normal dado que el paradigma de
programacin de Angular.js es muy diferente al de jQuery. Vamos a ir explicando
el cdigo poco a poco.

!
Angular y Directivas
!

Lo primero que podemos ver es que el fichero HTML tiene un atributo ng-app a
nivel de la etiqueta <html>

!
<html ng-app>
!

A este tipo de atributos se les conoce en el mundo de Angular como


directivas: es el concepto fundamental de todo el framework. Cada directiva tiene
una funcionalidad diferente. En nuestro caso la directiva ng-app se encarga de
definir los limites de la aplicacin Angular e inicializarla. En este caso, la aplicacin
Angular ocupa todo el documento HTML.

PGINA "15 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Una vez limitado el alcance de la aplicacin e introducido el concepto de directiva,


es el momento de avanzar.

Angular y Controladores

La siguiente directiva encontrada es la directiva ng-controller, que afecta al body, su


cdigo es :

!
<body ng-controller="controladorFactura">
!

Esta directiva tiene varias funcionalidades . La primera y ms importante es la


que define el concepto de Controlador. Un Controlador es un objeto que est
ligado con una vista.

!
!
Angular y Vistas
!
Una vista es un bloque de cdigo HTML. En Angular, un controlador est
relacionado con el bloque de cdigo HTML, que se encuentra dentro de la
etiqueta en la que lo hemos declarado. En nuestro caso el controlador ha sido
declarado a nivel de <body>.

<body ng-controller="controladorFactura">
PGINA "16 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Por lo tanto, la vista a la que el controlador est asociado es todo el <body> de
nuestro documento.

!
!
Angular Controladores y Javascript
!
Ya sabemos que un Controlador esta relacionado con una Vista. Para gestionar
esta relacin, debemos declarar una funcin de Javascript con el mismo nombre del
controlador. A travs de esta funcin nos comunicaremos con la vista.

function controladorFactura($scope) {
}

PGINA "17 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Angular y $scope

La funcin de JavaScript es muy sencilla, sin embargo puede generar dudas


inmediatas, ya que dispone de una variable denominada $scope. Qu es $scope?
:Es una variable que funciona como un contenedor compartido por el
Controlador y la Vista.

PGINA "18 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
!
!
As pues, si queremos asignar datos desde el controlador a la Vista, no tenemos mas
que insertarlos en la variable $scope. Automticamente, la vista se percatar de los
cambios que el $scope ha sufrido y se actualizar.

!
function controladorFactura($scope) {
!
$scope.factura = {"id":1,"concepto":"mac","importe":1000};
!
}
!
Angular y Expresiones

Para que la vista puede mostrar la informacin almacenada en el $scope usaremos


una expresin de Angular. Las expresiones son sencillos bloques de cdigo que
van entre {{ }} y que Angular es capaz de interpretar.
Vamos a verlo en cdigo :

<body ng-controller="controladorFactura">
<p>{{factura.id}}</p>
<p>{{factura.concepto}}</p>
<p>{{factura.importe}}</p>
</body>

De esta forma, la vista quedar completamente configurada para mostrar la


informacin de nuestra factura que se encuentra almacenada en el $scope as como
los cambios que en el $scope se produzcan. A diferencia del mundo de jQuery, en
las que las vistas no tienen responsabilidad ninguna, en este caso tienen la
responsabilidad de actualizar sus propios datos.

PGINA "19 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
As pues dar lo mismo las veces que cambiemos los datos que se encuentran
ubicados en el $scope: las vistas asumirn su responsabilidad y cambiarn la
informacin que se presenta.

PGINA "20 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Data Driven Design

Esta nueva forma de programar aplicaciones web se esta comenzando a denominar


Data Driven Design o Data Driven Development, ya que nos encontramos ante
una arquitectura que se centra en gestionar los datos y despus, a travs de
observadores, actualizarlos de forma transparente en la vista que corresponda.

!
!

PGINA "21 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Angular y Colecciones
En el captulo anterior hemos terminado de construir nuestro primer ejemplo con
Angular.js y el concepto de Factura. A travs de este ejemplo hemos explicado los
conceptos fundamentales. Es momento de continuar y ver cmo trabajar con una
coleccin o lista de Facturas.

!
Para ello, lo primero que vamos a hacer es generar un Array en Javascript al que
denominaremos listaFacturas y aadir otra Factura ms para tener dos. Hecho
esto, aadiremos la lista de Facturas al $scope de nuestro controlador.Vamos a verlo
detalladamente:

!
function controladorPersona($scope) {
!

var factura= {id":"A","concepto":"mac","importe":1000};


var factura2= {"id":"B","concepto":"Iphone","importe":700};
var listaFacturas=[];
listaFacturas.push(factura);
listaFacturas.push(factura2);
$scope.listaFacturas=listaFacturas;
}
PGINA "22 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
ng-repeat y listaFacturas

Es momento de modificar nuestra Vista para que sea capaz de presentarnos una
lista de Facturas. Para ello nos vamos a apoyar en la directiva ng-repeat
encargada de mostrar una lista de objetos que se encuentren almacenados en el
$scope.

Para ello construiremos una tabla y usaremos la directiva ng-repeat a nivel de <tr>

<table>

<tr ng-repeat="factura in listaFacturas">


<td>{{factura.id}}</td>
<td>{{factura.concepto}}</td>
<td>{{factura.importe}}</td>
</tr>

PGINA "23 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

</table>

Realizada esta operacin, las dos facturas que tenemos en la lista se muestran en la
pantalla.

ng-click y nuevas facturas.

El siguiente paso es aadir un nuevo botn a la Vista de tal forma que podamos
aadir nuevas facturas al Array que tenemos. Para ello nos apoyaremos en la
directiva ng-click.

<body ng-controller="controladorFacturas">
<table>
<tr ng-repeat="factura in listaFacturas">
<td>{{factura.id}}</td>
<td>{{factura.concepto}}</td>
<td>{{factura.importe}}</td>
</tr>
</table>
<input type="button" ng-click="addFactura()" value=nuevo/>
</body>

Como vemos, hemos usado la directivang-click que se encargar de recoger el


evento de pulsar el botn. Para gestionar este evento, modificaremos el $scope de
nuestro controlador y aadiremos la funcin addFactura().

PGINA "24 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

$scope.addFactura=function() {

$scope.listaFacturas.push({"id":"C","concepto":"Nexus","importe":300});
}

Esta funcin usar el mtodo push de la clase Array para aadir un nuevo
elemento a nuestra lista. Hecho esto, la lista contendr un nuevo registro.

!
Reglas de negocio

Frecuentemente debemos implementar reglas de negocio en nuestra aplicacin. En


este ejemplo vamos a aadir una regla de negocio sencilla, la capacidad de calcular
el importe con IVA de la Factura. Para ello, de entrada nos vamos a apoyar en
$scope y aadirle una nueva funcin.

!
$scope.calcularIva=function(factura) {
!

}

return factura.importe *1.21;

Hecha esta operacin, podremos modificar la vista y aadir una nueva columna
que nos presente el precio con IVA incluido.

<tr ng-repeat="factura in listaFacturas">


<td>{{$index+1}}</td>
<td>{{factura.id}}</td>
<td>{{factura.concepto}}</td>
<td>{{factura.importe}}</td>
PGINA "25 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

<td>{{calcularIva(factura)}}</td>
</tr>

La nueva tabla ser la encargada de calcular el precio con IVA:

Lamentablemente, no es la mejor opcin ya que pueden existir muchos


controladores que quieran calcular el IVA de una Factura concreta.

!
Reglas de negocio y Business Objects
!

Para solventar este problema, nos vamos a apoyar en los ejemplos habituales de
programacin orientada a objeto y vamos a crear una clase que contenga la
funcin y podamos as reutilizarla. Esto es algo para lo cual Angular no tiene gran
soporte.

PGINA "26 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Vamos a ver su cdigo :

!
function Factura(json) {
!
this.id=json.id;
this.concepto=json.concepto;
this.importe=json.importe

!
this.calcularIva= function () {
!

}

return this.importe*1.21;

!
}
!
Creada esta clase, podemos hacer uso de ella a la hora de crear nuestros objetos,
aadirlos a la lista y asignarlos al $scope.

var facturaDatos= {"id":"A","concepto":"mac","importe":1000};


var facturaDatos2= {"id":"B","concepto":"Iphone","importe":700};
var listaFacturas=[];
listaFacturas.push(new Factura(facturaDatos));
listaFacturas.push(new Factura(facturaDatos2));
$scope.listaFacturas=listaFacturas;

Construyendo los objetos de esta forma podremos hacer uso de la nueva funcin
que hemos creado a nivel de la Vista.

<tr ng-repeat="factura in listaFacturas">


<td>{{factura.id}}</td>
<td>{{factura.concepto}}</td>
<td>{{factura.importe}}</td>

<td>{{factura.calcularIva()}}</td>
</tr>

El resultado ser el mismo:

PGINA "27 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Borrar Facturas

Hemos terminado de construir las dos operaciones ms bsicas: listar Facturas y


aadir nuevas Facturas. Vamos a definir la operacin de borrado basndonos en lo
que hemos aprendido. En primer lugar, vamos a aadir una nueva columna a la
tabla que nos permita disponer de un botn de borrado al que asociaremos una
funcin.

<td>

<input type="button" ng-click="removeFactura(factura)"


value=Borrar"/>
</td>

Esto nos cambiar la forma en la que la tabla se muestra en algo semejante a lo


siguiente:

!
Implementada esta primera parte, aadimos una nueva funcin a nuestro $scope
que se encargue de eliminar un objeto de la lista. Para ello nos vamos a apoyar en
la funcin filter que tienen los Arrays de Javascript y que permiten realizar un
filtrado a partir de una condicin inicial.

$scope.removeFactura=function(factura) {

PGINA "28 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

!

!


}

WWWW.ARQUITECTURAJAVA.COM

$scope.listaFacturas=$scope.listaFacturas.filter(function (f) {

})

return f!==factura;

!
!

En este caso hemos definido un filtro que cumplirn todas las Facturas excepto la
situada en la fila que acabamos de pulsar. Por lo tanto, la nueva lista de Facturas
nicamente contendr una nica Factura.

!
ng-model y formularios

Hasta este momento hemos trabajado con Angular.js aadiendo nuevas facturas de
forma automtica. Pero esto no es realmente lo que queremos, sino que nos vendra
bien tener un formulario en el cul rellenar los distintos campos de la Factura.
Vamos a modificar nuestro HTML para aadirlo. Cada campo dispondr de una
directiva ng-model.

<form>
<p>
Id:<input type="text" ng-model="nuevaFactura.id"/>
</p>

<p>
Concepto:<input type="text" ng-model="nuevaFactura.concepto"/>
</p>
<p>
Importe:<input type="text" ng-model="nuevaFactura.importe"/>
</p>

PGINA "29 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
<input type="button" ng-click="addFactura()" value="nuevo"/>
</form>

Realizada esta primera modificacin, la pgina HTML mostrar un nuevo


formulario.

!
El uso de la directiva ng-model nos crear un nuevo objeto en el $scope que se
denomina nuevaFactura y que podemos aadir a la lista a travs de la funcin
addFactura():

$scope.addFactura=function() {

$scope.listaFacturas.push(new Factura($scope.nuevaFactura));
}

Angular, Visibilidad y Modulos

Ya est la aplicacin funcionando, sin embargo tenemos un problema y es que


nuestra funcin est definida a nivel global del cdigo de Javascript. Esto genera un
PGINA "30 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

problema de diseo, ya que cuando la aplicacin crezca de tamao, nos podemos


encontrar con funciones que tengan el mismo nombre en el mbito global.

!
Para evitar este problema y permitir que la aplicacin pueda crecer de tamao
vamos a incluir todo nuestro cdigo en un mdulo que es un patrn de diseo a
nivel de Javascript de tal forma que cada mdulo tenga sus propias funciones y nos
asle del resto.

PGINA "31 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Vamos a ver cmo queda en cdigo :
!
angular.module(moduloFacturas',[]).
controller("controladorFacturas",function($scope) {

var facturaDatos= {"id":"A","concepto":"mac","importe":1000};


var facturaDatos2= {"id":"B","concepto":"Iphone","importe":700};
var listaFacturas=[];
listaFacturas.push(new Factura(facturaDatos));
listaFacturas.push(new Factura(facturaDatos2));
$scope.listaFacturas=listaFacturas;
//resto de cdigo
});

Una vez realizada esta operacin, indicamos a Angular.js en qu mdulos se apoya


la aplicacin

<html ng-app=moduloFacturas">

Hemos terminado de gestionar las operaciones bsicas sobre nuestra tabla


utilizando Angular. Sin embargo nos quedan muchas tareas que realizar, ya que en
estos momentos tenemos todos los datos almacenados en el Cliente. Es momento
de comenzar a trabajar con un servidor.

PGINA "32 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Angular.js y Node.js
!
Por ahora la aplicacin que hemos desarrollado nos funciona en nuestro navegador
pero en ningn momento se conecta con el servidor para almacenar o leer datos de
forma remota. Es momento de abordar este problema, para ello vamos a usar
como tecnologa Node.js aunque podramos haber usado cualquier otra tecnologa
desde PHP, Java o .NET para lanzar servidor. He elegido Node.js por su sencillez.

Que es Node.js?

Node.js no es ni ms ni menos que el motor V8 de Javascript de Google Chrome


modificado para que pueda correr en un entorno servidor e interpretar el cdigo
Javascript que nosotros solicitemos.

!
Instalacin de Node.js
!
PGINA "33 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

La instalacin de Node.js vara segn la plataforma pero suele ser siempre


relativamente sencilla. Para instalar Node.js iremos a su pagina web y nos
descargaremos la versin correspondiente.

http://nodejs.org/

En la instalacin solo hay que seguir los pasos del asistente. Terminada la
instalacin, abrimos una consola de sistema y comprobamos que Node.js funciona.
Para ello, desde la consola de consola escribiremos node y pulsaremos enter.

!
Acabamos de entrar en la consola de Node.: nos aparece un simbolo > para que
empecemos a escribir comandos sobre el interprete de Node. Escribimos uno de los
comandos mas sencillos de Javacript : console.log (hola node); pulsamos intro y
nos imprimir el mensaje por pantalla.

!
Una vez realizada esta operacin, escribimos process().exit(); y salimos del
interprete de Node. Volvemos a estar a nivel de consola de sistema operativo.

PGINA "34 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Node y NPM

Una de las ventajas que tiene Node es que es un sistema extremadamente modular
que nos permite hacer prcticamente cualquier cosa. Eso s, para hacerla
tendremos que instalar los mdulos que correspondan.

!
En nuestro caso vamos a convertir Node en un servidor Web que nos pueda enviar
informacin en formato JSON que es lo que necesitamos para nuestra aplicacin
cliente. Para ello necesitamos instalar Express.js , que es un framework MVC de
Servidor para Node. Vamos a utilizar ahora otra herramienta de Node : NPM
( Node Packaged Modules ) que nos instala cualquier mdulo necesario . Desde la
consola escribimos:

npm install express

Puede haber gente que en sistemas linux necesite ejecutarlo con el


comando sudo. Si la ejecucin es correcta, nos instalar el framework con las
dependencias necesarias y veremos en la consola algo similar a esto.

PGINA "35 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Node y Servidor
!
Una vez instaladas las dependencias, es momento de crear nuestro primer
programa en Node.js . As pues, crearemos un fichero que se llame
ServidorNodePubica.js con el siguiente contenido.

//////// Creo Facturas//////


var listaFacturas=[];

var facturaDatos= {"id":"A","concepto":"mac","importe":1000};


var facturaDatos2= {"id":"B","concepto":"Iphone","importe":700};

listaFacturas.push(facturaDatos);
listaFacturas.push(facturaDatos2);

!
///////// Cargo Express ////////////
!
var express=require("express");
var app=express();

PGINA "36 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
///////// URL de Facturas ////////////
!
app.get("/facturas",function(req,res) {
!
res.send(listaFacturas);
!
});
!
///////// Inicio el Servidor ////////////
!
var servidor= app.listen(3000,function() {



console.log("servidor arrancado puerto 3000");
});

A pesar de la sencillez del cdigo, ste merece una explicacin detallada. En primer
lugar genero la lista de Facturas que antes tena en el cliente desde el servidor, ya
que las vamos a solicitar va Ajax.

!
var listaFacturas=[];
!

var facturaDatos= {"id":"A","concepto":"mac","importe":1000};


var facturaDatos2= {"id":"B","concepto":"Iphone","importe":700};

listaFacturas.push(facturaDatos);
listaFacturas.push(facturaDatos2);

El segundo paso es iniciar el framework Express.js y generar una url /facturas


que nos devuelva la lista de facturas en formato JSON.

!
///////// Cargo Express ////////////
!
var express=require("express");
var app=express();

!
!
///////// URL de Facturas ////////////
!
app.get("/facturas",function(req,res) {
!
PGINA "37 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

res.send(listaFacturas);

!
});
!

Por ltimo, solicito a Express.js que inicie un Servidor en el puerto 3000.

///////// Inicio el Servidor ////////////

var servidor= app.listen(3000,function() {




console.log("servidor arrancado puerto 3000");
});

!
!

Realizadas todas estas operaciones, salvamos este fichero en la carpeta actual


donde usamos npm y le llamamos ServidorNodePublica .js. El siguiente paso es
arrancar la aplicacin ejecutando:

!
node ServidorNodePublica.js
!

Realizadas estas operaciones abrimos un navegador ya accedemos a la Url que nos


devolver la lista

Node y Angular.js

Hemos terminado de instalar Node y configurarlo como servidor Web. Ahora


podemos instalar nuestra aplicacin en el servidor. Para ello vamos a construir una
carpeta que se denomine publica donde almacenaremos el fichero HTML que
tenemos , el javascript de Angular.js y nuestra Factura.
PGINA "38 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Realizada esta operacin, modificaremos el fichero de Servidor de Node para que
aada una carpeta de contenidos estticos a la que podamos acceder.

!
app.use("/",express.static(__dirname+"/publica",'public'));
!
var servidor= app.listen(3000,function() {



console.log("servidor arrancado puerto 3000");
});

!
Como vemos, el cdigo a incluir es muy sencillo pues se trata de una nica lnea.
!
app.use("/",express.static(__dirname+"/publica",'public'));
!
Esta lnea da de alta la carpeta publica como recurso accesible desde un
navegador. Una vez hecho esto, podemos solicitar sin ningn problema el fichero
aplicacion.html al servidor. Reiniciamos node (lo paramos con Ctrl C y lo
volvemos a lanzar ) La aplicacin de Angular.js carga sin problemas y hemos
terminado de configurar un servidor bsico.

PGINA "39 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
En el siguiente captulo comenzaremos a trabajar con Ajax
!

PGINA "40 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Angular y Ajax
En el captulo anterior hemos configurado Node.js para que nos sirva como
Servidor Web. Es momento de comenzar a utilizarlo con Angular. En estos
momentos nuestra aplicacin carga una lista de Facturas en el $scope de su
controlador.

var facturaDatos= {"id":"A","concepto":"mac","importe":1000};


var facturaDatos2= {"id":"B","concepto":"Iphone","importe":700};
var listaFacturas=[];
listaFacturas.push(new Factura(facturaDatos));
listaFacturas.push(new Factura(facturaDatos2));
$scope.listaFacturas=listaFacturas;

Es momento de comenzar a realizar los primeros cambios y cargar esta lista desde
el Servidor. Para ello, el primer paso ser modificar nuestra aplicacin Cliente para
que tenga las capacidades de realizar una peticin HTTP.

!
!
!

El servicio de $http

Hemos estado usando durante los captulos anteriores la variable $scope. Esta
variable nos permite almacenar objetos que son compartidos entre el controlador y
la vista. $scope es un ejemplo de servicio a nivel de Angular. Un servicio,
como su nombre indica, es una clase que provee de una funcionalidad determinada
al framework. En el caso del $scope permite compartir objetos entre la Vista y el
Controlador.

PGINA "41 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Vamos a introducir en este capitulo un nuevo servicio, el servicio de $http que
evidentemente est orientado a realizar peticiones HTTP va Ajax. Si recordamos,
PGINA "42 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

en el captulo anterior hemos definido una Url que nos devuelve una lista de
Facturas en el Servidor.

As pues, el siguiente paso es introducir y usar el servicio $http de Angular para


traernos los datos del Servidor al cliente.

!
!

Usando $http

Para poder comenzar a usar el servicio, deberemos inyectarlo a nivel del mdulo de
igual forma que en los primeros captulos inyectamos $scope.

Vamos a ver como se implementa en cdigo :

!
!

angular.module('moduloFacturas',
[]).controller("controladorFacturas",function($scope,$http) {

PGINA "43 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Una vez que hayamos inyectado el servicio de $http, podemos pasar a usarlo. Para
ello invocaremos la Url de /facturas utilizando su mtodo get(). Realizada esta
operacin, invocaremos el mtodo de callback de toda llamada Ajax, que aqu se
denomina success().

!
var peticion= $http.get("facturas");
!

peticion.success(function(listaFacturas) {
var listaObjetosFacturas=[];
for (var i=0;i<listaFacturas.length;i++) {

listaObjetosFacturas.push(new Factura(listaFacturas[i]));
}
$scope.listaFacturas=listaObjetosFacturas;
});

Como puede verse, realizamos una peticin $http que nos devuelve una lista de
Facturas en formato JSON, la cul convertimos a un Array de Objetos y aadimos
al $scope.

PGINA "44 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Hemos eliminado la lista de objetos que tenamos en el Cliente la hemos


substituido por una peticin Ajax de servidor . El resultado es idntico a los
ejemplos anteriores, solamente que en este caso los datos se cargan desde Node.js.

!
!

$http y POST

El siguiente paso ser insertar nuevas Facturas en el Servidor a travs de una


peticin de tipo POST usando el servicio $http.

Para ello deberemos modificar nuestra aplicacin de Servidor para que soporte
peticiones de tipo POST. Al ser Node y Express productos muy modulares,
necesitamos instalar un nuevo mdulo que soporte este tipo de
peticiones. As pues volveremos a usar la herramienta npm y ejecutaremos la
siguiente instruccin:

!
npm install body-parser
!

Esta extensin nos permitir utilizar Node.js para gestionar de una forma sencilla
las peticiones POST. Realizada esta operacin, simplemente usamos el framework
Express.js con el nuevo mdulo y aadimos una nueva ruta que capture las
peticiones de tipo POST y nos aada una nueva Factura a la lista que tenemos en
el servidor.

var bodyParser = require('body-parser');


app.use( bodyParser.json() );
app.post("/facturas",function(req,res) {

listaFacturas.push(req.body);
res.send(ok);

});

PGINA "45 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Hemos terminado de construir la parte del Servidor. Nos queda por completar la
parte que es puramente de Cliente. Vamos a ver como gestionarla desde Angular:

$scope.addFactura=function() {

!
var peticion= $http.post("facturas",$scope.nuevaFactura);
!
peticion.success(function(mensaje) {
!

});
}

console.log(ok);

Como podemos ver, la operativa es realmente intuitiva usamos $http.post y le


pasamos una nueva factura.

!
var peticion= $http.post("facturas",$scope.nuevaFactura);
!

Hecho esto, habremos insertado un nuevo registro a nivel del servidor. Sin
embargo la parte cliente no est actualizada, as pues deberemos realizar otra
peticin Ajax dentro del mtodo success de la peticin POST que vuelta a
seleccionar la lista de Facturas.

PGINA "46 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

As pues el mtodo success() de nuestra peticin post deber implementar el


siguiente cdigo que nos refresque la lista:

peticion.success(function(datos) {

var peticion= $http.get(facturas");

peticion.success(function(listaFacturas) {






var listaObjetosFacturas=[];
for (var i=0;i<listaFacturas.length;i++) {






listaObjetosFacturas.push(new Factura(listaFacturas[i]));



}

!
$scope.listaFacturas=listaObjetosFacturas;
!
});
});

Acabamos de construir el cdigo de la aplicacin que es capaz de listar e insertar


datos en el Servidor va Ajax.

PGINA "47 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

$http y DELETE

!
!

Nos queda todava una ultima operacin por realizar: la operacin de borrado.
Nos encontramos ante una casustica similar a la anterior y por lo tanto
necesitamos implementar el lado Servidor primero para luego enlazar con el
Cliente.
Vamos a ver como quedara la aplicacin de Node.js a nivel de Servidor cuando
gestiona una peticin de borrado utilizando una peticin DELETE:

!
app.delete("/facturas/id/:id",function(req,res) {
!
listaFacturas=listaFacturas.filter(function (factura) {
!

});

return req.params.id!==factura.id;

res.send(ok);
});

Como podemos ver, la peticin de DELETE nicamente recibe el id de la Factura


que queremos borrar. Una vez recibido, se encarga de borrar la Factura usando la
funcin de filter. Nos queda por implementar la parte del Cliente en Angular . Para
ello vamos a usar $http su mtodo delete.

!
$scope.removeFactura=function(factura) {
!
var peticion= $http.delete("facturas/id/"+factura.id);
!
peticion.success(function(datos) {
!

//resto de cdigo
});


}

Acabamos de borrar la factura del servidor como nos paso anteriormente pero
debemos volver a actualizar la lista y para ello, en el mtodo success realizaremos
una peticin GET.
PGINA "48 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
El cdigo ser el siguiente:
!
peticion.success(function(datos) {





var peticion= $http.get("facturas");

!

!

!




peticion.success(function(listaFacturas) {
var listaObjetosFacturas=[];
for (var i=0;i<listaFacturas.length;i++) {





listaObjetosFacturas.push(new Factura(listaFacturas[i]));


}

!

$scope.listaFacturas=listaObjetosFacturas;
!
!

});
!
});
!

Hemos terminado de realizar las operaciones con el servicio de $http y todo


funciona de forma correcta. Sin embargo hay algo que podemos mejorar.

PGINA "49 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Angular y DRY Networking

El problema que tenemos en estos momentos es que estamos realizando ms


peticiones HTTP de las que realmente necesitamos ya que nos estamos
trayendo una nueva lista de facturas cada vez que insertamos o
borramos contenido para actualizar nuestra lista. Pronto nos daremos
cuenta de que tenamos cargada la lista de Facturas en el Cliente salvo la ltima.
Lo nico que necesitamos es aadir la nueva Factura que acabamos de insertar a
nivel de servidor en el Cliente y no volver a recargar la lista por completo.
Vamos a modificar el cdigo que tenemos a nivel de Servidor para gestionar la
peticin POST de una forma mejor y que nos devuelva nuestra factura.

app.post("/facturas",function(req,res) {

listaFacturas.push(req.body);
res.send(req.body);

});

La operacin que estamos realizando es bastante sencilla. Estamos insertando la


Factura a nivel de servidor y una vez insertada la estamos devolviendo como
respuesta de la peticin POST en formato JSON. De esta forma, con una nica
peticin HTTP podemos actualizar el Servidor y actualizar el Cliente. Sin tener
que repetir continuamente el envo de la lista de Facturas actualizada. Hecho esto,
el cdigo Cliente de Angular.js quedar mucho ms sencillo.

!
!

$scope.addFactura=function() {



var peticion= $http.post("facturas",$scope.nuevaFactura);

!

!

peticion.success(function(factura) {



});

$scope.listaFacturas.push(factura);

PGINA "50 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Borrado y DRY Neworking

La misma operativa se puede definir para la accin de borrar. Modificaremos el


cdigo del servidor para que nos devuelva el id de la Factura que deseamos
eliminar del Cliente.

!
app.delete("/facturas/id/:id",function(req,res) {
!
!
listaFacturas.filter(function (factura) {
!

});

return req.params.id!==factura.id;

var peticion= $http.delete("facturas/id/"+factura.id);


peticion.success(function(id) {
$scope.listaFacturas=$scope.listaFacturas.filter(function (factura) {


});

!
res.send(req.params.id);
!
});
!
!
Modificaremos el cdigo de Cliente para que nos elimine el elemento de la lista.
!
!
$scope.removeFactura=function(factura) {
!
!

return id!==factura.id;

}
}

Hemos terminado de simplificar el uso del servicio $http reduciendo las peticiones
y el trfico de datos entre cliente y servidor. Hemos aplicado el principio DRY pero
a nivel de red (DRY NETWORKING). Est claro que no siempre podremos
aplicar este principio ya que existen casos en los que otras aplicaciones actualizan
PGINA "51 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

los datos. En este tipo de situaciones deberemos apoyarnos en conceptos ms


avanzados que quedan fuera del contenido del libro y que se denominan
promesas.

!
El servicio $window
!

Para familiarizarnos con el uso de servicios, vamos a utilizar otro de los ms


habituales: el servicio $window. $window nos da acceso a los cuadros de dilogo de
Javascript (confirm,alert,prompt). Vamos a usarlo para pedir confirmacin de la
eliminacin de registros. El primer paso como siempre ser inyectar el servicio.

!
Vamos a ver el cdigo :
!
angular.module('moduloFacturas',[]).controller("controladorFacturas",

function($scope,$http,$window) {

Realizado este primer paso, vamos a utilizar el servicio en el evento de borrar para
primero pedir confirmacin y luego borrar el registro en caso afirmativo.

!
$scope.removeFactura=function(factura) {
!

PGINA "52 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

if($window.confirm("deseas borrar la factura con el


concepto:"+factura.concepto)) {

!
var peticion= $http.delete("facturas/id/"+factura.id);
!
peticion.success(function(id) {
!
$scope.listaFacturas=$scope.listaFacturas.filter(function (factura) {
!

});

});
}
}

return id!==factura.id;

Una vez construido el cdigo, si pulsamos sobre el botn de borrar, nos saldr el
siguiente mensaje.

!
!
Hemos terminado de gestionar las peticiones Ajax y de introducir el concepto de
servicio es momento de seguir avanzando.

!
!

PGINA "53 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Creacin de Servicios
!
En el capitulo anterior hemos usado fundamentalmente el servicio $http para
gestionar las peticiones Ajax con el Servidor. En este capitulo vamos a intentar
organizar un poco ms nuestra aplicacin, separando an ms las
responsabilidades. En este momento es el controlador el que se encarga de
gestionar prcticamente todo. Vamos a aislar la responsabilidad de las peticiones
Ajax de los propios controladores .

!
As, otros controladores u otras piezas de la aplicacin pueden usarlas y de esta
manera el cdigo es reutilizable. Para poder realizar esta operacin deberemos
crear nuestros propios Servicios especializados.

PGINA "54 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

!
Creacin
!

WWWW.ARQUITECTURAJAVA.COM

de ServicioFacturas

Igual que en los primeros captulos del libro hemos creado el ControladorFacturas
dentro del mdulo de Facturas, en este captulo crearemos un Servicio dentro del
mdulo al cul denominaremos ServicioFacturas. Vamos a ver cmo se
implementa a nivel de cdigo:

angular.module('moduloFacturas').controller("controladorFacturas",

function($scope,$http,$window,servicioFacturas) {

!
// cdigo del controlador omitido
!

}).service("servicioFacturas", function($http){



this.listaFacturas=function() {

!

!


!

!

return $http.get("facturas");

this.addFactura=function(factura) {

return $http.post('/facturas',factura);
}
this.removeFactura=function(factura) {

return $http.delete('/facturas/id/'+factura.id)


}
});

Acabamos de crear el Servicio como un elemento dentro del Mdulo. Un Servicio


es una clase Singleton que agrupa un conjunto de funcionalidad con el objetivo de
poderse reutilizar.

!
!

PGINA "55 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Una vez creado el servicio, el controlador podr hacer uso de l. Para ello
deberemos inyectarlo como pasa con el resto de servicios que ya tenemos.

PGINA "56 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

El cdigo es similar a situaciones anteriores :

angular.module('moduloFacturas',[]).controller("controladorFacturas",

!
!

function($scope,$http,$window,servicioFacturas) {

Realizada esta operacin, nuestro controlador podr delegar en la clase de servicio


para realizar todas las llamadas Ajax.

!
Veamos cmo queda el controlador una vez realizados los cambios y construido el
servicio en el cual delega una gran parte de su funcionalidad

PGINA "57 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Vamos a verlo en cdigo :

!
var peticion= servicioFacturas.listaFacturas();
!

peticion.success(function(listaFacturas) {
!


var listaObjetosFacturas=[];
!




!

!
!

for (var i=0;i<listaFacturas.length;i++) {





listaObjetosFacturas.push(new Factura(listaFacturas[i]));

}

$scope.listaFacturas=listaObjetosFacturas;


});


$scope.addFactura=function() {


var peticion=
servicioFacturas.addFactura($scope.nuevaFactura);

!

!

peticion.success(function(factura) {


});

$scope.listaFacturas.push(new Factura(factura));

!
!
$scope.removeFactura=function(factura) {
!
if($window.confirm("deseas borrar la factura con el
concepto:"+factura.concepto)) {

!
var peticion= servicioFacturas.removeFactura(factura);
!
PGINA "58 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
peticion.success(function(id) {
!
$scope.listaFacturas=$scope.listaFacturas.filter(function (factura) {
!

});

});
}

return id!==factura.id;

Como podemos ver los cambios no son complejos y simplemente substituimos el


uso de $http por el uso del ServicioFacturas.

!
!

Servicios y Objetos

En estos momentos tenemos una funcionalidad candidata a ser parte de un


Servicio. Me refiero al siguiente bloque de cdigo, que se encarga de convertir una
estructura JSON proveniente del servidor en un conjunto de objetos de Javascript.

!
var listaObjetosFacturas=[];
!

for (var i=0;i<listaFacturas.length;i++) {







listaObjetosFacturas.push(new Factura(listaFacturas[i]));



}

Para evitar repeticiones de cdigo vamos a convertir tambin esta lgica en un


servicio al que llamaremos conversorObjetos:

.service(conversorObjetos", function(){

this.convertirFacturas=function(listaFacturas) {

!

!

!

var listaObjetosFacturas=[];

for (var i=0;i<listaFacturas.length;i++) {

PGINA "59 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

!
});
!

WWWW.ARQUITECTURAJAVA.COM


listaObjetosFacturas.push(new Factura(listaFacturas[i]));

}
return listaObjetosFacturas;

Realizada esta operacin, el siguiente paso ser que nuestro Controlador utilice
este servicio.

Como siempre inyectamos el nuevo servicio que nos ayuda a simplificar el cdigo :

function($scope,$http,$window,
servicioFacturas,conversorObjetos) {

PGINA "60 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!

var peticion= servicioFacturas.listaFacturas();
!

peticion.success(function(listaFacturas) {
!

$scope.listaFacturas=conversorObjetos.convertirFacturas(listaFacturas);
!
});
!
Hemos aprovechado el captulo para crear dos Servicios y dividir mejor las
responsabilidades, aislando el controlador de las llamadas Ajax y de las
transformaciones.

!
!

PGINA "61 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Angular y SPA
En el captulo anterior hemos organizado el cdigo de la capa de Servicios. Es
momento de organizar el cdigo que est ms ligado a la capa de presentacin. En
estos momentos tenemos una pgina que incluye una lista y un formulario.

Es evidente que sta no es la estructura de elementos que deseamos. Vamos a


dividir nuestra aplicacin utilizando dos DIV de HTML, de tal manera que cada
uno de estos elementos incluya una de las vistas.

!
!

PGINA "62 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Directiva ng-show
!
Acabamos de aadir dos divisores a la aplicacin que delimitan cada una de las
Vistas que la aplicacin va a tener. Vamos a aadir a cada uno de los <divs> una
directiva ng-show que nos permitir determinar cundo una parte de la aplicacin
se muestra y cuando se oculta.

PGINA "63 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Vamos a terminar de clarificar las ideas mostrando el nuevo cdigo HTML:
!
!
<body ng-controller="controladorFacturas">

<div ng-show="mostrarLista">
<table >
<tr ng-repeat="factura in listaFacturas">
<td>{{factura.id}}</td>
<td>{{factura.concepto}}</td>
<td>{{factura.importe}}</td>
<td>{{factura.calcularIva()}}</td>
<td><input type="button" ng-click="removeFactura(factura)" value="Borrar"/></
td>
</tr>
</table>
<input type="button" ng-click="verFormulario()" value="nuevo"/>
</div>

<div ng-show="mostrarFormulario">
<form>
<p>
Id:<input type="text" ng-model="nuevaFactura.id"/>
</p>

<p>
Concepto:<input type="text" ng-model="nuevaFactura.concepto"/>
</p>
<p>
Importe:<input type="text" ng-model="nuevaFactura.importe"/>
</p>

<input type="button" ng-click="addFactura()" value="nuevo"/>


</form>
</div>
</body>

!
!

Como podemos ver, hemos aadido etiquetas <div> y la directiva ng-show. Eso s,
cada directiva ng-show est ligada a una variable que deberemos asignar en el
$scope.

PGINA "64 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
<div ng-show=mostrarLista">
<div ng-show="mostrarFormulario">

$scopes y variables

Vamos a ver detalladamente las modificaciones de cdigo que tenemos que hacer a
nivel de nuestro controlador para gestionar los divs que acabamos de crear:

$scope.mostrarFormulario=false;
$scope.mostrarLista=true;

!
var peticion= servicioFacturas.listaFacturas();
!
peticion.success(function(listaFacturas) {


$scope.listaFacturas=conversorObjetos.convertirFacturas(listaFacturas);


$scope.mostrarFormulario=false;
$scope.mostrarLista=true;


});


$scope.addFactura=function() {

!

!


var peticion= servicioFacturas.addFactura($scope.nuevaFactura);
peticion.success(function(factura) {

$scope.listaFacturas.push(new Factura(factura));

$scope.mostrarFormulario=false;
$scope.mostrarLista=true;

});

!
!
!
$scope.verFormulario=function() {
!
PGINA "65 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

$scope.mostrarFormulario=true;
$scope.mostrarLista=false;

!
//omitimos el cdigo de eliminar
!
!
Como podemos ver, ahora tenemos dos nuevas variables en el $scope:
!
$scope.mostrarFormulario=false;
$scope.mostrarLista=true;

Son las encargadas de mostrar y ocultar una u otra vista. Para ello hemos aadido
un nuevo botn debajo de la tabla .

!
<input type="button" ng-click="verFormulario()" value="nuevo"/>
!
Esto nos permitir cambiar de la Vista de tabla a la de Formulario

!
Para ello hemos creado una funcin a nivel del $scope que intercambia los valores
de la vista.

!
$scope.verFormulario=function() {
!

!
!
}
!

$scope.mostrarFormulario=true;
$scope.mostrarLista=false;

PGINA "66 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Pulsando este botn pararemos a la Vista de formulario y podremos aadir una


nueva Factura.

!
Una vez implementado todo, la aplicacin se comportar como una Aplicacin
SPA. SPA (Simple Page Application): se trata de una aplicacin que tiene todas
sus vistas cargadas en un nico fichero HTML y las va intercambiando.

PGINA "67 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
La directiva ng-switch
!
Aunque hemos conseguido separar las vistas, lo hemos hecho de una forma muy
elemental. Vamos a trabajarlo un poco ms a travs de la directiva ng-switch que
nos permite reducir ms el cdigo. Para ello vamos a definir un <div> que
englobe a los dems:

<body ng-controller="controladorFacturas">

<div ng-switch="vista">
<div ng-switch-when="lista">
<table >
<tr ng-repeat="factura in listaFacturas">
<td>{{factura.id}}</td>
<td>{{factura.concepto}}</td>
<td>{{factura.importe}}</td>
<td>{{factura.calcularIva()}}</td>
<td><input type="button" ng-click="removeFactura(factura)" value=Borrar"/>
</td>
</tr>
</table>
<input type="button" ng-click="verFormulario()" value="nuevo"/>
</div>

<div ng-switch-when="formulario">
<form>
<p>
Id:<input type="text" ng-model="nuevaFactura.id"/>
</p>

<p>
Concepto:<input type="text" ng-model="nuevaFactura.concepto"/>
</p>
<p>
Importe:<input type="text" ng-model="nuevaFactura.importe"/>
</p>

<input type="button" ng-click="addFactura()" value="nuevo"/>


</form>
</div>
</div>

PGINA "68 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Las directivas son similares a las de ng-show , lo que simplificaremos ser el cdigo
del controlador que quedar como sigue :

$scope.vista="lista";
$scope.nuevaFactura={};

var peticion= servicioFacturas.listaFacturas();


peticion.success(function(listaFacturas) {

$scope.listaFacturas=conversorObjetos.convertirFacturas(listaFacturas);


$scope.vista="lista";

});


$scope.addFactura=function() {

console.log($scope.nuevaFactura);
var peticion= servicioFacturas.addFactura($scope.nuevaFactura);

!
peticion.success(function(factura) {
!

$scope.listaFacturas.push(new Factura(factura));

$scope.vista="lista";

});
}

!
$scope.verFormulario=function() {
!

$scope.vista="formulario";
!
!
}
!
En este caso, como podemos ver, con una nica variable gestionamos ambas vistas.
Sin embargo nos queda solventar un problema. Para una aplicacin pequea este
sistema funciona correctamente. Ahora bien, cuando la aplicacin
incremente su tamao, tendremos que cargar de forma inicial cientos
de Vistas lo cul no es viable

PGINA "69 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

En el siguiente captulo abordaremos esta problemtica.

!
!

PGINA "70 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Angular y ngRoute
Cuando la aplicacin vaya creciendo de tamao necesitaremos aplicar otro
enfoque que nos permita una mayor flexibilidad. Para ello vamos a instalar una
extensin de Angular.js que se denomina ng-route e implementa un
sistema de enrulado que aporta mayor flexibilidad y permite la carga
dinmica de contenidos.

!
Instalacin ng-route

La instalacin del sistema de enrulado no es excesivamente compleja . El primer


paso es el obtener el nuevo modulo de enrulado. Para ello vamos a la zona de
descargas de Angular.js y pulsamos sobre extras o mdulos adicionales.

PGINA "71 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
!
Una vez situados en extras, seleccionamos el fichero de angular-route.js y lo
descargamos .

!
!
Obtenido el fichero, el siguiente paso es ubicarlo dentro de nuestro HTML
!
!
<script type="text/javascript" src="factura.js">
</script>

<script type="text/javascript" src="angular.min.js">

PGINA "72 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

</script>

<script src="angular-route.js" type="text/javascript">


</script>

!
Configuracin del mdulo
!
Nosotros ya tenemos configurado un mdulo que es el mdulo de nuestra
aplicacin moduloFacturas. Vamos a inyectar el mdulo de ngRoute dentro de
nuestro mdulo para poder usarlo sin problemas.

Vamos a mostrar el cdigo fuente y comentarlo en detalle:

angular.module(moduloFacturas',['ngRoute'])
.constant('baseUrl', 'http://localhost:3000/')
.config(function($routeProvider,$locationProvider) {

!
$locationProvider.html5Mode(true);
!
});
!

El cdigo no es tan complejo como pueda parecer al principio. Tenemos dos


nuevos conceptos que explicar. El primero de ellos es el concepto de Constante,
que hace referencia a un valor no modificable de la aplicacin. En nuestro caso se
define la Url del servidor de donde nos vamos a bajar la aplicacin.

PGINA "73 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
!
constant('baseUrl', http://localhost:3000/')
!
El segundo concepto es la parte de configuracin que se ejecuta cuando el
framework se inicializa. En nuestro caso estamos inyectando dos objetos
$locationProvider y $routeProvider.

El $locacinProvider se encarga de establecer el modo en las que las URL del


navegador se generan. En este caso, apoyndose en HTML5 de tal forma que,
cuando cambiemos de Vista, la URL que muestra el navegador cambie tambin.

Plantillas y $routeProvider

El proveedor de rutas es otro servicio que nos permitir cambiar dinmicamente la


vista que tenemos seleccionada. Para poder utilizar el proveedor de rutas, primero
deberemos partir nuestra aplicacin SPA en varias vistas, cada una almacenada en
un fichero de plantilla.

!
!
!
!

PGINA "74 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Para ello vamos a crear una carpeta de plantillas y ubicar en ella nuestras dos
vistas a las que denominaremos (listaFactura.tpl y formularioFactura.tpl)

!
La directiva ng-view
!
Realizada esta operacin, vamos a usar una nueva directiva que se denomina ngview para cargar una plantilla u otra en la pgina de forma dinmica. Para ello
eliminaremos todo el contenido HTML que tenamos y dejaremos
simplemente un div con la directiva ng-view.

PGINA "75 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Vamos a verlo en cdigo :

<body ng-controller="controladorFacturas">
<div ng-view></div>

</div>
</body>

El sistema de enrutado ser el encargado de cargar una vista u otra dependiendo


de lo que nosotros solicitemos.

!
!
El cdigo usa el mtodo when del $routeProvider para cargar una plantilla u otra:

!
.config(function($routeProvider,$locationProvider) {
!
$locationProvider.html5Mode(true);

$routeProvider.when("/vistaListaFacturas",{

PGINA "76 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

!

!

WWWW.ARQUITECTURAJAVA.COM

templateUrl:"/plantillas/listaFacturas.tpl"


});
$routeProvider.when("/vistaFormularioFacturas",{


templateUrl:"/plantillas/formularioFactura.tpl"
});
$routeProvider.otherwise({


templateUrl:"/plantillas/listaFacturas.tpl"
});
});

El servicio $location

Una vez realizada esta operacin, nos queda ver como nos cambiamos de vista
utilizando los botones de la aplicacin. Para ello el primer paso es inyectar el
servicio de localizacin a nivel de nuestro controlador

PGINA "77 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Vamos a ver el cdigo:

controller("controladorFacturas",

function($scope,$http,$window,servicioFacturas,conversorObjetos,

$location) {

..

}
El siguiente paso es utilizar el servicio de $location para cambiar de vista segn
vamos pulsando los diferentes botones.

PGINA "78 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
!
Vamos a mostrar los bloques de cdigo que varan:
!
$scope.verFormulario=function() {
!

$location.path("/vistaFormularioFacturas");
!
!
}
$scope.addFactura=function() {

!

!




}

console.log($scope.nuevaFactura);
var peticion= servicioFacturas.addFactura($scope.nuevaFactura);
peticion.success(function(factura) {



});

$scope.listaFacturas.push(new Factura(factura));
$scope.vista="lista";
$location.path("/vistaListaFacturas");

PGINA "79 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
!
Como podemos ver, es muy sencillo de manejar: simplemente usamos el servicio de
$location con su mtodo path y cambiamos la URL segn nuestras necesidades :

!
$location.path("/vistaListaFacturas");
!

A partir de este momento, la aplicacin tendr una estructura SPA, pero cargar
todos los contenidos de forma dinmica.

!
!

PGINA "80 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Angular Directivas
Uno de los conceptos que ms diferencia a Angular.js de otros frameworks es el
concepto de Directiva. En muchas ocasiones cuando programamos una web, nos
encontramos con la necesidad de cambiar contenido de forma dinmica. Por
ejemplo, podemos tener una tabla HTML y queremos cambiar dinmicamente el
color de una celda cuando pasamos por encima.

Normalmente este efecto lo solemos implementar con jQuery y el evento hover de


la siguiente forma o similar:

$( tablaA tr" ).hover(


function() {
$( this ).css(background-color,lightblue);
}, function() {
$( this ).css(background-color,)}
);

El resultado ser el siguiente:

PGINA "81 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Reutilizacin de cdigo

Aunque este tipo de efectos quedan muy bien y se construyen con JQuery de una
forma muy rpida, tienen un problema muy importante. JQuery est muy centrado
en la capa de presentacin y muy ligado a ella.

PGINA "82 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
En nuestro caso, este efecto est ligado a la tablaA, sin embargo tendremos
muchas tablas en nuestra aplicacin segn sta crezca (Arquitectura SPA). As pues,
no es tan fcil reutilizar el cdigo de jQuery como nosotros queremos. Ahora
mismo afecta slo a una tabla, podemos modificarlo para que quizs afecte a
todas , pero no es tan fcil adaptarlo mucho ms all de esto. Tenemos un
problema con el principio DRY (Dont Repeat Yourselft).

Creacin de directivas

Angular soluciona este problema ya que nos permite crear nuestras propias
directivas a nivel de cdigo que luego podremos reutilizar a voluntad. Crear una
directiva es bastante sencillo pero convertirse en experto es diferente. Vamos
a crear un par de directivas elementales para explicar el concepto. La primera es
una directiva que simplemente saca un mensaje por consola cuando la aplicamos:

!
.directive("mensaje",function() {
!

return {
!


link: function(scope,elem,attr) {
!



})

console.log("mi directiva");

Las directivas tienen una funcin de link que se ejecuta cuando dicha directiva se
procesa. Esta funcin recibe tres parmetros el scope en el cual se ejecuta, el
elemento en el que nos encontramos y los atributos que este elemento tiene. En
nuestro primer ejemplo no vamos a hacer uso de ninguno de los parmetros
simplemente vamos a usar la directiva para imprimir un mensaje por la consola.
Para ello tendremos que modificar nuestro cdigo HTML y aadir la directiva:

PGINA "83 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
<div>
<table >
<tr ng-repeat="factura in listaFacturas" mensaje>

<td>{{factura.id}}</td>
<td>{{factura.concepto}}</td>
<td>{{factura.importe}}</td>
<td>{{factura.calcularIva()}}</td>
<td><input type="button" ng-click="removeFactura(factura)" value="Borrar"/
></td>
</tr>
</table>
<input type="button" ng-click="verFormulario()" value="nuevo"/>
</div>

Hecho esto, la directiva se procesar y por cada Factura nos imprimir un mensaje
por la consola.

Acabamos de crear la directiva ms sencilla.

Directiva Iluminar

Es evidente que la directiva que acabamos de crear no sirve para ms que clarificar
el concepto. Vamos a construir una nueva directiva que implemente la misma
funcionalidad habida en el ejemplo inicial de jQuery (ilumina la fila) . Llamaremos
a esta directiva iluminar:

PGINA "84 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
.directive("iluminar",function() {
!

return {
!


link: function(scope,elem,attr) {
!



elem.bind('mouseenter',function(evento) {
!


});

elem.bind('mouseleave',function(evento) {


});


});

!
!

!
!

elem.css("background-color","lightblue");

elem.css("background-color","");

El cdigo es bastante sencillo de entender ya que Angular usa una versin reducida
de jQuery que se denomina jQLite para realizar las modificaciones en la capa de
presentacin. En este caso usamos la funcin de bind() para crear dos eventos
mouseenter y mouseleave, que se encargarn de cambiar el color de la
fila por la cual pasemos el ratn. Evidentemente para que esto funcione
necesitamos aplicar la nueva directiva:

<tr ng-repeat="factura in listaFacturas" iluminar>

<td>{{factura.id}}</td>
<td>{{factura.concepto}}</td>
<td>{{factura.importe}}</td>
<td>{{factura.calcularIva()}}</td>
<td><input type="button" ng-click="removeFactura(factura)" value="Borrar"/
></td>
</tr>

PGINA "85 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

</table>
<input type="button" ng-click="verFormulario()" value="nuevo"/>
</div>

El resultado a nivel de capa de presentacin ser idntico al de jQuery:

!
La ventaja que tenemos ahora es que la directiva se ha definido una vez y la
podemos aplicar a conveniencia en los bloques de cdigo que deseemos, a
diferencia de JQuery que se aplica a un conjunto de nodos determinados

PGINA "86 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
!
Las directivas son una parte fundamental de Angular.js y abren unas posibilidades
de extensibilidad gigantescas. Son tambin uno de los conceptos ms difciles de
abordar y de convertirse en experto.

!
!

PGINA "87 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Angular y Organizacin
!
Hemos tratado en los anteriores captulos muchos conceptos y ahora dichos
conceptos estn agrupados. Es momento de organizar un poco ms el cdigo de tal
forma que nos sea ms sencillo trabajar.

Para ello vamos a construir la siguiente estructura de carpetas diseada de forma


que cada tipo de responsabilidad est separada ( esta es una estructura muy bsica
ya que tenemos poco cdigo)

!
Aplicacin.html
!

En primer lugar tenemos el fichero aplicacin.html que va a quedar prcticamente


vaco a nivel de contenido, ya que delegar en los otros para cargar los ficheros
segn la necesidad.

!
!

PGINA "88 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

<html ng-app="moduloFacturas">
<head>
<script type="text/javascript" src="script/factura.js">
</script>
<script type="text/javascript" src="script/angular.min.js">
</script>
<script type="text/javascript" src="script/angular-route.js">
</script>

!
<script type="text/javascript">
!
var modulo = angular.module('moduloFacturas',['ngRoute']);
!
</script>
!

<script src="rutas/rutas.js" type="text/javascript">


</script>
<script src="directivas/directivas.js" type="text/javascript">
</script>
<script src="servicios/servicios.js" type="text/javascript">
</script>
<script src="controladores/controladores.js" type="text/javascript">
</script>
</head>
<body ng-controller="controladorFacturas">
<div ng-view></div>
</div>
</body>
</html>

Una vez tenemos claro como queda este fichero, lo vamos a revisar lnea a lnea.

Carpeta Script

Esta carpeta contendr todos los ficheros .js que necesitamos para inicializar
Angular pero que no corresponden a la aplicacin en s.

<script type="text/javascript" src="script/factura.js">


</script>
<script type="text/javascript" src="script/angular.min.js">

PGINA "89 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

</script>
<script type="text/javascript" src="script/angular-route.js">
</script>

Carpeta Rutas

Esta carpeta contendr el sistema de rutas de la aplicacin. En nuestro caso se


trata de un sencillo fichero rutas.js con el siguiente cdigo:

modulo.constant('baseUrl', 'http://localhost:3000/')
.config(function($routeProvider,$locationProvider) {

!

!
!

!

!

$locationProvider.html5Mode(true);

$routeProvider.when("/vistaListaFacturas",{

templateUrl:"/plantillas/listaFacturas.tpl"

});
$routeProvider.when("/vistaFormularioFacturas",{


templateUrl:"/plantillas/formularioFactura.tpl"
});
$routeProvider.otherwise({


});

!
!

templateUrl:"/plantillas/listaFacturas.tpl"

!
});
!
Carpeta Directivas
!
Esta carpeta puede que termine conteniendo muchas directivas. En nuestro caso
solo contiene una ya que el ejemplo era muy sencillo.

!
modulo.directive("iluminar",function() {
!

return {
!

PGINA "90 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!

!

link: function(scope,elem,attr) {

elem.bind('mouseenter',function(evento) {


});

elem.bind('mouseleave',function(evento) {


});


});

!
!

!
!

elem.css("background-color","lightblue");

elem.css("background-color","");

!
Carpeta Controladores
!
Esta carpeta contendr el controlador con el que hemos estado trabajando durante
todo el libro y cuyo cdigo es el ms extenso.

modulo.controller("controladorFacturas",

function($scope,$http,$window,servicioFacturas,conversorObjetos,
$location) {

!

!

!

!

$scope.nuevaFactura={};
var peticion= servicioFacturas.listaFacturas();
peticion.success(function(listaFacturas) {



$scope.listaFacturas=conversorObjetos.convertirFacturas(listaFacturas);



});


$scope.addFactura=function() {

console.log($scope.nuevaFactura);

PGINA "91 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!

!

var peticion= servicioFacturas.addFactura($scope.nuevaFactura);




});

peticion.success(function(factura) {
$scope.listaFacturas.push(new Factura(factura));
$scope.vista="lista";
$location.path("/vistaListaFacturas");

!
!
$scope.removeFactura=function(factura) {
!

if($window.confirm("deseas borrar la factura con el
concepto:"+factura.concepto)) {

!

!
!

!

var peticion= servicioFacturas.removeFactura(factura);

peticion.success(function(id) {



$scope.listaFacturas=$scope.listaFacturas.filter(function
(factura) {




});
}


});

return id!==factura.id;

!
$scope.verFormulario=function() {
!

$location.path("/vistaFormularioFacturas");
!
!
}
!
})
!
!
PGINA "92 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Carpeta de Servicios

Esta carpeta almacena los servicios que, en nuestro caso, contiene tanto el
servicioFacturas como el conversorObjetos.

modulo.service("servicioFacturas", function($http){

!

!

this.listaFacturas=function() {

!

!

!

!

!

!

return $http.get("facturas");

this.addFactura=function(factura) {

return $http.post('/facturas',factura);

}
this.removeFactura=function(factura) {

return $http.delete('/facturas/id/'+factura.id)

}).service("conversorObjetos", function(){

!

!
!

!

!




this.convertirFacturas=function(listaFacturas) {

var listaObjetosFacturas=[];

for (var i=0;i<listaFacturas.length;i++) {


listaObjetosFacturas.push(new Factura(listaFacturas[i]));

}
return listaObjetosFacturas;

});

PGINA "93 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Carpeta de Plantillas

Esta carpeta se encarga de almacenar las plantillas con las distintas vistas que
Angular.js soporta.

!
!
Hemos terminado de organizar la aplicacin de Angular.js de una forma mucho
ms modular(existen muchas variaciones). De esta forma podemos ver de una
manera mucho ms clara cmo se dividen las responsabilidades en una Aplicacin
Angular y cmo cada uno de los conceptos ocupa su lugar dentro de las tpicas
arquitecturas MVC.

PGINA "94 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
A este modelo que tiene tantas opciones en cuanto a la gestin de las capas se le
suele denominar MVW (Model View WhatEver), ya que Angular soporta una
gran flexibilidad en cuanto al patrn MVC se refiere.

PGINA "95 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

!
Conclusiones
!
Han quedado muchas cuestiones que tratar de Angular.js tales como filtros,
resources, watches, promesas, validaciones , directivas complejas etc. Angular es un
universo nuevo que ha venido para quedarse, junto con los nuevos frameworks de
Javascript como Backbone, Ember o Meteor y se har en los prximos aos un
hueco importante en la forma que tenemos de programar aplicaciones web.
Tenemos que irlos conociendo paulatinamente e integrar estos nuevos conceptos en
nuestras futuras arquitecturas. Espero que esta introduccin ayude a aclarar dudas.
Puedes ponerte en contacto conmigo va :
Correo:
[email protected]

LinkedIn
https://www.linkedin.com/profile/view?id=2949192&trk=tab_pro

Twitter
https://twitter.com/arquitectojava

PGINA "96 DE "97

ARQUITECTURAS WEB CON ANGULAR.JS

WWWW.ARQUITECTURAJAVA.COM

Bibliografia
Desarrollo Agil con Angular.js (Carlos Azaustre)
Pro Angular JS (Adam Freeman)
Mastering Web Application with AngularJS (Pawel Kozlowski)

!
!
!

PGINA "97 DE "97

También podría gustarte