Aplicaciones en Angular
Una aplicación Angular es un conjunto de módulos donde cada módulo debe ocuparse de un conjunto cohesivo de elementos para manipular un concepto lógico del dominio del problema. Un módulo en Angular contiene un conjunto de directivas, servicios, fábricas, constantes, controladores y otros elementos.
Los elementos básicos que una aplicación Angular debe tener son:
- Los módulos: sirven para contener partes funcionalmente cohesivas de una aplicación. Por ejemplo, en una aplicación de venta de libros podemos decidir que en un módulo tenemos la funcionalidad racionada con los libros, en otro la relacionada con los autores, otro con los clientes, otro con las ventas, etc.
- Los templates: Los templates o vistas con los elementos html (extendidos con las directivas angular) que van a permitir que un usuario visualice e interactue con la aplicación. Para cada módulo se diseñarán sus correspondientes vistas. Las vistas despliegan información de la aplicación y tienen asociadas en sus elementos de interacción, por ejemplo en los botones, acciones o funciones que la aplicación debe ejecutar para lograr los objetivos de la aplicación.
- Los controladores: Los controladores se asocian con las vistas y contienen las acciones que se van a invocar desde ellas.
En la siguiente figura, un usuario interactura con una vista de una aplicación y al interactuar con los elementos de la interface, se invocan acciones que están definidas en el controlador:
Los módulos
Un módulo angular define una aplicación. Un módulo es el contenedor de elementos de la aplicación como los controladores, los filtros, etc.
Tomando el ejemplo básico "Hello World" de la documentación oficial de Angular
Un módulo se define utilizando la función angular.module('nombredelmodulo', [])
En el segundo parámetro de tipo arreglo, que en el ejemplo está vacío []
, se incluyen las dependencias del módulo, es decir referencias a otros módulos que se van a utilizar aquí. Si el módulo no tiene dependencias igual se debe definir el parámetro pero vacío. Si se omite este parámetro, Angular lo interpretará como una invocación al módulo y no como una declaración de un módulo. En el siguiente ejemplo se está definiendo un módulo llamado holaMundoEjemplo
en la línea 1. Este módulo no tiene dependencias por eso los []
. La variable app contendrá la definición del módulo.
En la línea 2, se está agregando al módulo un controller
. Cada controlador tiene un nombre, en el ejemplo es 'holaMundoControlador'
y el código de una función, en el ejemplo es la holaMundoControlador
que se esta invocando sin los ()
. En este caso el código está definido en la línea 4.
Otra manera de escribir la creación del controlador es incluir directamente la definición de la función en el argumento del controlador:
Una aplicación puede tener muchos módulos. Lo que convierte un módulo en la aplicación principal es la referencia que se hace a él en él desde las vistas de la utilizando la directiva ng-app
. En el siguiente código vemos esto. En la línea 11 , asociado con el tag body
está la directivang-app
cuyo valor es el nombre del módulo que definimos que se convertirá en el módulo principal.
Los controladores se asocian con elementos del template. En el ejemplo, en la línea 12, utilizando la directiva ng-controller
estamos asociando con ese elemento div
(y todo lo que él contiene) el controlador que definimos llamado holaMundoControlador
.
Note que en la línea 15, la expresión saludo
no está definida en la vista entonces debe ser algo que esté definido en el controlador holaMundoControlador
:
EL siguiente diagrama muestra parte de los objetos javascript que crea Angular, para el ejemplo anterior, y las relaciones entre ellos.
Data binding
Las variables definidas utilizando ng-model
en el template, se transforman en nodos DOM. Además, quedan creadas en una zona lógica de Angular llamada el scope
. La variable $scope
es una variable predefinida de angular. Los valores de las variables que se guarden allí siempre estarán sincronizados entre la vista y el controlador; evitando que el desarrollador tenga que actualizar explícitamente las vistas de la interface. En el ejemplo anterior podemos ver este comportamiento en los siguientes casos:
- la variable
nombre
se inicializa en el controlador y este valor automáticamente se despliega en la vista dentro del campo de texto como valor inicial. - la variable
nombre
cambia cuando el usuario ingresa un valor en el campo de texto. En el controlador se refleja el nuevo valor en$scope.nombre
. - la variable
saludo
obtiene valor solo en el controlador pero como se utiliza en la vista en la expresión{{saludo}}
la vista se actualiza cada vez que en el controlador se cambia su valor.
Angular se ocupa de establecer un enlace entre las variables del template y el scope
, de tal forma que cuando se actualicen sus valores en un lado, se actualizará automáticamente en el otro.
Ejemplo Shopping cart (básico) en angular
Primero definimos un prototipo de cómo debería verse la aplicación:
Segundo diseñamos la estructura de datos. Podemos utilizar una clase UML para representar las propiedades de la estructura y los métodos que se necesitan:
La estructura tiene un arreglo de ítems
donde cada uno tiene su descripción, cantidad y costo. Los métodos corresponden con los requerimientos definidos antes
Template
La estructura es la que se presenta en el siguiente fragmento. Note la directiva ng-app
y ng-controller
. Lo segundo que hay que notar es la inclusión de la librería angular
(líneas 5). Hay que entender dos cosas:
- se debe incluir porque se utiliza en el proyecto. En este caso, la librería está en un directorio local del proyecto que se llama
bower_components
. - la información de qué versión de angular estamos utilizando y de cómo la descargamos la podemos revisar en el enlace: Administrar librerías javascript.
En este ejemplo utilizamos una tabla para presentar los elementos del shopping cart. La relación entre el template y el controlador está en los tags:
ng-model
para indicar variables de la estructura.ng-click
para invocar los métodos del controlador.
Adicionalmente, estamos utilizando la directiva angular ng-repeat
que facilita la iteración sobre la lista de los ítems y los filtros {% raw %}{{expresión | filtro}}{% endraw %}
que facilita cambiar elementos en el DOM.
El Controlador
El controlador es una función constructora de objetos que representa la estructura del invoice
y sus métodos. Note que tanto la estructura como los métodos quedan en la variable $scope
de angular.
Ver el ejemplo Completo en Plunker | Descargar el ejemplo de Github |
---|---|
Plunker | Github |