2.8 Modulos

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.

Usando módulos

Veamos ahora distintas operaciones sobre los módulos.

Crear un módulo

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.

Recuerda poner los corchetes al crear un módulo:
angular.module("AA",[]);

Obtener un módulo

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.

Crear y obtener un módulo

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?

Artefactos

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.

Controladores

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";
});

  • Línea 1: La variable 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.
  • Línea 3: Creamos un controlador llamado “PruebaController”, el cual añadimos al 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.

Todos los controladores que usemos en nuestra aplicación deben siempre definirse dentro de un módulo y no como funciones sueltas. É es importante ya que a partir de la versión 1.3 de AngularJS no funcionarán los controladores que no estén dentro de un módulo.

Directivas

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.

Otros artefactos

Hasta ahora hemos visto que AngularJS dispone de 2 artefactos :

  • Controladores
  • Directivas

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:

  • Filtros
  • Constantes
  • Servicios
  • Factorias
  • Providers
  • Config
  • Run
  • Etc.

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.

Dependencias

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"]);

  • Línea 1: Se crea el módulo “A”
  • Línea 2: Se crea el módulo “B”
  • Línea 4: Se crea el módulo “app” pero indicamos que depende de los módulos “A” y “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.

Transitividad

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"]);

  • Línea 1: Ahora creamos un nuevo módulo llamado “T”
  • Línea 3: El módulo “A” ahora depende del módulo “T”

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”.

Carga de módulos

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.

Recuerda que siempre debes cargar todos los ficheros JavaScript con la etiqueta <script>. AngularJS no se encarga de ello aunque cree las relaciones entre los módulos.

Varios 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

La mayor utilidad de los módulos es si está haciendo una librería que será usada por terceros.

Espacio de nombres

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.

Mi opinión personal y mi recomendación es que en unos años acabaremos teniendo nombres de módulos y artefactos como las FQCN 4) de Java.

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”

Ejemplo

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&oacute;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&ntilde;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()
  }
});

  • Línea 3: Vemos cómo el controlador ya no es una función con nombre sino que ahora es una función anónima que se pasa al método controller junto con el nombre del controlador que sigue siendo SeguroController. Es decir que ahora el controlador se define dentro del módulo.

Referencias

1) pero aún quedan muchas por ver
2) he usado esa palabra aunque no exista en la documentación de AngularJS
3) Ya veremos posteriormente como la forma correcta sería pasar un array
4) Fully-Qualified Class Name. Es decir el nombre completo de una clase Java incluyendo el paquete al que pertenece.
5) Lo mismo para otros artefactos
unidades/02_angular/08_modulos.txt · Última modificación: 2014/10/28 18:35 por admin
Ir hasta arriba
CC Attribution-Share Alike 3.0 Unported
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0