Por ahora hemos visto unas cuantas directivas de angular 1). Pasemos a explicar qué son los módulos en AngularJS.
En todos los ejemplo que hemos visto ya hemos hecho uso de los módulos en AngularJS con la siguiente línea:
var app=angular.module("app",[]);
Pero, ¿qué es un módulo? Podríamos verlo como un paquete de Java. Es como una forma de agrupar funcionalidades de Angular. Por ejemplo, podríamos crear varias directivas relacionadas con google Maps. Lo normal sería agrupar todas esas directivas en un único módulo y luego al crear nuestra aplicación decir que vamos a usar dicho módulo.
Sigamos viendo lo que es un módulo mediante los métodos de JavaScript que ofrece AngularJS.
Veamos ahora distintas operaciones sobre los módulos.
Podemos crear un módulo llamado “AA” mediante la siguiente línea:
angular.module("AA",[]);
Al ejecutarlo se crea el módulo “AA”. Aunque no contiene ninguna funcionalidad, será necesario añadirla posteriormente.
¿Por qué debemos incluir los corchetes? Desgraciadamente no existe un método para obtener una referencia a un módulo y otro distinto para crear . En ambos casos se usa el método module()
. Si incluimos un segundo parámetro con los corchetes, estamos indicando que se está creando , pero si no incluimos el segundo parámetro lo que hacemos es pedir un módulo que ya existe.
angular.module("AA",[]);
Para obtener una referencia a un módulo ya creado usaremos la siguiente línea:
var moduloAA=angular.module("AA");
Ahora en la variable de JavaScript moduloAA
tenemos una referencia al módulo llamado AA
, el cual existía previamente.
Lo normal no es crear un módulo y luego obtener una referencia a él sino hacerlo todo en la misma línea:
var moduloAA=angular.module("AA",[]);
Ahora en la variable de JavaScript moduloAA
tenemos una referencia al módulo llamado AA
, el cual acabamos de crear.
¿Se entiende ahora la primera línea de todos los ejemplos de AngularJS?
En los módulos se pueden definir diversos artefactos 2) que permitirán configurar nuestra aplicación.
Un artefacto es por ejemplo una directiva o un controlador , teniendo que definir estos artefactos en módulos de AngularJS.
Por ahora hemos visto que crear un controlador es simplemente crear una función JavaScript con el nombre de dicho controlador. Esta no es una forma adecuada de crear un controlador, lo correcto es añadir el controlador al módulo de nuestra aplicación.
var app=angular.module("app",[]); app.controller("PruebaController",function($scope) { $scope.mensaje="Hola Mundo"; });
app
contiene una referencia al módulo que acabamos de crear llamado app
. Esta variable app
contiene ,entre otros, un método llamado controller
que nos permite añadir controladores a nuestro módulo.app
.
El método controller
acepta dos parámetros, el primero es el nombre del controlador y el segundo la función 3) con el código JavaScript del controlador.
Hemos visto algunas directivas en AngularJS pero nosotros podemos crear nuestras propias directivas, para ello deberemos usar el método directive
del módulo.
app.directive('mapa', function() { });
Ya veremos más adelante cómo crear nuevas directivas pero por ahora simplemente recordad que al igual que los controladores, las directivas deben añadirse a un módulo.
Hasta ahora hemos visto que AngularJS dispone de 2 artefactos :
AngularJs dispone de otros tipos de artefactos que iremos viendo a lo largo del curso y que también deben añadirse a los módulos:
Es decir y para acabar con la explicación de qué es un módulo:
Un módulo es donde se añaden los distintos artefactos que usaremos en nuestra aplicación.
En cualquier aplicación que desarrollemos acabaremos organizando nuestro código en distintos módulos o usando módulos de terceros.
¿Cómo indicamos que AngularJS debe cargar el código de los otros módulos? Es decir, ¿cómo le decimos que nuestro módulo depende de otros módulos? Por fin vamos a explicar el significado de los corchetes al crear un módulo. Si sabes algo de JavaScript ya habrás deducido que los 2 corchetes corresponden a un array vacío. Pero, ¿qué significado tiene dicho array? Pues son la lista de nombre de módulos de los que dependemos.
Veamos un ejemplo:
var moduloA=angular.module("A",[]); var moduloB=angular.module("B",[]); var app=angular.module("app",["A","B"]);
¿Qué implicaciones tiene que el módulo “app” dependa de los módulos “A” y “B”?
AngularJS por defecto sólo nos permite usar los artefactos que hemos definido en nuestro módulo principal ,es decir, en el que hemos indicado en la directiva ng-app
en el tag <html>
que en nuestros ejemplos es el módulo app
. El resto de módulos aunque los creemos no se podrán utilizar ya que el módulo principal no depende de ellos. Por ello la dependencia de módulos permite que podamos usar los artefactos de otros módulos.
La carga de módulos es transitiva , veamos un ejemplo:
var moduloT=angular.module("T",[]); var moduloA=angular.module("A",["T"]); var moduloB=angular.module("B",[]); var app=angular.module("app",["A","B"]);
Ahora el módulo “app” depende de los módulos “A” y “B” pero el módulo “A” a su vez depende del módulo “T”. ¿Qué implica ésto? Que en nuestra aplicación podremos usar cualquier artefacto definido en los módulos “app”, “A”, “B” y “T”.
Llegados a este punto , parece que los módulos son una cosa muy útil para organizar nuestro código JavaScript y con las relaciones transitivas nos podemos ahorrar mucho trabajo.
Pero hay un asunto en el que no habrás caído: para que funcione todo ésto, todo el código JavaScript debe estar cargado en la página. ¿Cómo? Sí, te estoy diciendo que aún debes seguir añadiendo manualmente todos tus ficheros “js” con todo el código JavaScript.
AngularJS no va a ahorrarte cosas como lo siguiente:
<script type='text/javascript' src='T.js'></script> <script type='text/javascript' src='A.js'></script> <script type='text/javascript' src='B.js'></script> <script type='text/javascript' src='app.js'></script>
Es decir , suponiendo que cada módulo y todos sus artefactos están en un único fichero , deberemos cargar los 4 ficheros explícitamente en el index.html
.
Sin embargo , aunque AngularJS no tenga nada referido a la carga de ficheros JavaScript sí hay otros proyectos que pueden ayudarnos como:
Aunque hay que tomarlos con cautela ya que aún no hay una solución definitiva a la carga de ficheros JavaScript.
<script>
. AngularJS no se encarga de ello aunque cree las relaciones entre los módulos.
Entonces , ¿para qué sirve tener más de un módulo? Si estás haciendo una librería JavaScript con artefactos de Angular , como por ejemplo directivas para usar Google Maps en AngularJS debes de añadirlas a un módulo y como no puedes saber el nombre del módulo de la aplicación principal deberás crearte tu propio módulo. Éste es el primer motivo para crear nuevos módulos. Por otro lado dentro del código de la propia aplicación, ¿tiene sentido tener varios módulos? Discutiremos éste tema en Único módulo
Una última característica de los módulos es el espacio de nombres. Hemos visto que al añadir un controlador a un módulo le indicamos su nombre, pues bien. Para AngularJS da igual el módulo en el que definamos el controlador, siempre nos referiremos a él por su nombre independientemente del módulo en el que se haya definido.
Ésto tiene la ventaja de que no debemos preocuparnos por saber en qué módulo se definió el controlador (o cualquier otro artefacto) pero la parte negativa es que no podremos tener 2 controladores con el mismo nombre aunque estén en distintos módulos. Por lo tanto en un equipo grande de desarrollo se deberán coordinar los nombres de todos los artefactos de AngularJS.
Es decir que el nombre de un controlador 5) acabará siendo: “com.miempresa.miapp.subsistema.NombreControlador” y de esa forma evitaremos los solapamientos.
Y lo mismo con el nombre de los módulos que se llamarán “com.miempresa.miapp.subsistema”
Seguimos ahora con nuestro ejemplo y vamos a definir nuestro controlador en el módulo de nuestra aplicación.
<!DOCTYPE html> <html ng-app="app"> <head> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script> <script src="script.js"></script> </head> <body ng-controller="SeguroController"> <form> <fieldset> <legend>Seguro Médico</legend> <label for="nif">NIF:</label><input id="nif" name="nif" type="text" ng-model="seguro.nif" /><br> <label for="nombre">Nombre:</label><input id="nombre" name="nombre" type="text" ng-model="seguro.nombre" /><br> <label for="ape1">1º Apellido:</label><input id="ape1" name="ape1" type="text" ng-model="seguro.ape1" /><br> <label for="edad">Edad:</label><input id="edad" name="edad" type="text" ng-model="seguro.edad" /><br> <label for="sexo">Sexo:</label><select id="sexo" name="sexo" type="checkbox" ng-model="seguro.sexo" ><option value="">--Elige opcion--</option><option value="H">Hombre</option><option value="M">Mujer</option></select><br> <label for="casado">Casado:</label><input id="casado" name="casado" type="checkbox" ng-model="seguro.casado" /><br> <label for="numHijos">Nº Hijos:</label><input id="numHijos" name="numHijos" type="text" ng-model="seguro.numHijos" /><br> <label for="embarazada">Embarazada:</label><input id="embarazada" name="embarazada" type="checkbox" ng-model="seguro.embarazada" /><br> <label for="fechaCreacion">Fecha de creación:</label><input id="fechaCreacion" name="fechaCreacion" type="text" ng-model="seguro.fechaCreacion" /><br> </fieldset> <fieldset> <legend>Coberturas</legend> <label for="oftalmologia">Oftalmologia:</label><input id="oftalmologia" name="oftalmologia" type="checkbox" ng-model="seguro.coberturas.oftalmologia" /><br> <label for="dental">Dental:</label><input id="dental" name="dental" type="checkbox" ng-model="seguro.coberturas.dental" /><br> <label ng-show="seguro.sexo==='M'" for="fecundacionInVitro">Fecundacion In Vitro:</label><input ng-show="seguro.sexo==='M'" id="fecundacionInVitro" name="fecundacionInVitro" type="checkbox" ng-model="seguro.coberturas.fecundacionInVitro" /><br> </fieldset> <fieldset> <legend>Enfermedades</legend> <label for="corazon">Corazon:</label><input id="corazon" name="corazon" type="checkbox" ng-model="seguro.enfermedades.corazon" /><br> <label for="estomacal">Estomacal:</label><input id="estomacal" name="estomacal" type="checkbox" ng-model="seguro.enfermedades.estomacal" /><br> <label for="rinyones">Riñones:</label><input id="rinyones" name="rinyones" type="checkbox" ng-model="seguro.enfermedades.rinyones" /><br> <label for="alergia">Alergia:</label><input id="alergia" name="alergia" type="checkbox" ng-model="seguro.enfermedades.alergia" /><br> <label for="nombreAlergia">Nombre de la alergia:</label><input ng-disabled="seguro.enfermedades.alergia===false" id="nombreAlergia" name="nombreAlergia" type="text" ng-model="seguro.enfermedades.nombreAlergia" /><br> </fieldset> </form> </body> </html>
El fichero index.html
no se ha modificado
var app=angular.module("app",[]); app.controller("SeguroController",function($scope) { $scope.seguro={ nif:"", nombre:"", ape1:"", edad:undefined, sexo:"", casado:false, numHijos:undefined, embarazada:false, coberturas: { oftalmologia:false, dental:false, fecundacionInVitro:false }, enfermedades:{ corazon:false, estomacal:false, rinyones:false, alergia:false, nombreAlergia:"" }, fechaCreacion:new Date() } });
controller
junto con el nombre del controlador que sigue siendo SeguroController
. Es decir que ahora el controlador se define dentro del módulo.