Uno de los puntos fuertes de AngularJS es su flexibilidad para poder desarrollar y mantener aplicaciones de forma sostenible. En la programación actual esto es un punto crucial por lo que si nuestro framework lo ofrece de entrada el camino es mucho más interesante.  Con AngularJS podemos dividir el código de forma totalmente reusable en componentes llamados Modulos. Un Módulo AngularJs es básicamente un contenedor que agrupa diferentes componentes de tu aplicacion bajo un mismo nombre.

Detengamonos un momento y volvamos a revisar nuestro proyecto Seed. Como habrás visto, este proyecto contiene diferentes módulos definidos ( directives.js, filters.js, controllers.js,etc) que a su vez se incluyen en nuestro script principal (app.js), esto significa que un módulo en AngularJS (myApp en nuestro ejemplo) puede depender de otros módulos.  Por último en el  HTML (index.html) le indicamos a AngularJS que inicie nuestra aplicación utilizando el módulo myApp como punto de partida (Esto se realiza escribiendo en el tag <HTML> el atributo ng-app=”myApp”).

Así como podemos crear nuestros propios módulos, AngularJS tambien posee módulos incorporados en él, el módulo ng por ejemplo define muchas directivas, filtros y servicios para nuestro uso, de hecho en el proyecto Seed se han utilizado algunas directivas de este módulo como por ejemplo ng-model, ng-controller, etc.

 

Creando nuestro primer módulo

Para crear un módulo, debemos llamar al método angular.module(). Esta función acepta 2 argumentos, el primero es el nombre del módulo que estamos definiendo y el segundo argumento es un arreglo que define los módulos adicionales de los cuales éste módulo dependerá. Si no tenemos módulos del cual dependerá nuestro módulo, simplemente pasaremos un arreglo vacio, veamos un ejemplo:

1
2
angular.module('primerModulo',[]);  //define un modulo sin dependencias
angular.module('primerModulo',['moduloA','moduloB']); //define  un modulo con 2 dependencias

Una vez que hayamos creado nuestro módulo podemos incluir diferentes componentes a él.  Una manera sencilla de ver los módulos es como un objeto al cual podemos ir registrando componentes de forma dinámica, por ejemplo:

1
2
3
4
5
6
7
8
var primerModulo = angular.module('primerModulo',[]); //definimos nu modulo
primerModulo.controller('controlador1',function($scope){ // registramos el controlador
//codigo del controlador
});
primerModulo.directive('directiva1',function(){    // registramos una directiva
return {
};
});

El código anterior supone una mala práctica. Y es que cuando creamos y almacenamos un módulo dentro de una variable, ésta es añadida al scope global de Javascript, y esto no es una buena idea ya que estaríamos llenando el scope global de forma innecesaria.

Una mejor aproximación del código anterior y que evita que llenemos el scope global es incluir nuestro código anterior en una función IIFE (Immediately-invoked function expression) de la siguiente forma:

1
2
3
4
5
6
7
8
9
10
(function() {
var primerModulo= angular.module('primerModulo', []); //primerModulo ya no es global aquí
primerModulo.controller('primerControlador', function($scope) { // registramos el controlador
//codigo del controlador
});
primerModulo.directive('primeraDirectiva', function() { // registramos la directiva
return {
};
});
})();

Afortunadamente, para facilitarnos aún más la vida, AngularJS posee otro mecanismo, el cual es muy superior a la solución anterior. Cuando llamamos al método angular.module() con los 2 argumentos, AngularJS crea un nuevo módulo, cuando llamemos de forma subsecuente al mismo método (pero sólo con el nombre del módulo creado) AngularJs nos retornará el módulo creado, con esto en mente podremos utilizarlo de forma encadenada ( Ruby Style) de la siguiente forma:

1
2
3
4
5
6
7
8
angular.module('primerModulo',[]); // definimos el modulo y la lista de dependencias
angular.module('primerModulo').controller('primerControlador',function($scope){   //ahora simplemente lo usamos
//codigo del controlador
});
angular.module('primerModulo').directive('primeraDirectiva',function(){ // solo lo usamos
return {
};
});

Y siendo más exquisitos ( y más Ruby Style) :

1
2
3
4
5
6
angular.module('primerModulo',[]).controller('primerControlador',function($scope){
//codigo del controlador
}).directive('primeraDirectiva',function(){ //mi directiva
return {
};
});

 

A tener en cuenta: Debes tener cuidado cuando llames al método angular.module() multiples veces, es decir, sólo la primera llamada a dicho método se debe realizar con los 2 argumentos y las siguientes con el argumento del nombre del módulo, si tu llamas reiteradas veces al método con ambos argumentos estarás redefiniendo la lista de dependencias y no obteniendo el módulo existente. De la misma forma puedes utilizar el mismo método angular.module(‘nombre_modulo’) en diferentes archivos de codigo fuente para obtener el módulo creado.

 

Programación Modular ( Buenas Prácticas)

Al trabajar con AngularJS y organizar nuestro código podemos optar por 2 vias:

 

Modularización por capas

Esta forma de organización consiste en ordenar tú código por el tipo de componente que realiza dentro de la aplicación. Por ejemplo en nuestro proyecto Seed, podemos ver dentro del directorio app/js los siguientes archivos :

  • app.js
  • controllers.js
  • directives.js
  • filters.js
  • services.js

Como ves, cada tipo de componente va a un módulo en especifico,  y el módulo principal (que está definido en app.js) en el cual se definen las dependencias a los otros módulos. Este tipo de modularización es muy útil en diversos escenarios, por ejemplo para encontrar un fallo en particular digamos en un controlador o en un servicio ya sabes a donde ir. Pero ¿que pasa si nuestra aplicación crece en terminos de complejidad y funcionalidades? A lo mejor ¿puede no ser tan buena idea no?. Para estos casos existe la modularización por funcionalidades.

 

Modularización por funcionalidades

Este tipo de organización consiste en ubicar el código según la funcionalidad que preste dentro de la aplicación, supongamos que tenemos una aplicación tipo blog, así tendremos un módulo para el login de usuario, otro para comentarios y otro para los artículos. De esta forma nos resultará altamente efectivo ubicar cada controlador, filtro, directiva, etc en su correspondiente directorio según la funcionalidad que presten, esto nos permite reutilizar dicho módulo en otros proyectos (simplemente tomando dicho directorio) así como suministrar a diferentes equipos de desarrollo carga de trabajo de forma simultánea sin que tengan que estar estrechamente relacionados. Otro punto más a favor de esta forma de organización son los test unitarios, éstos serán muchos más sencillos ya que nos permitirá aislar y probar cada funcionalidad por separado. El siguiente snippet nos muestra como quedaría nuestro proyecto Seed redefinido por las funcionalidades de un blog:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/app
/img -- imagenes a nivel de aplicacion
/css --  CSS a nivel de aplicacion
/js
app.js -- modulo principal
/modules
/login  -- Directorio para funcionalidad Login
/js
controllers.js --controlador para el modulo Login
directives.js --directivas para el modulo Login
/views -- vistas para modulo Login
/css
/img
loginModule.js -- Modulo principal del modulo Login
/comment
/js
controllers.js --controladores para el modulo comentarios
directives.js --directivas para el modulo comentarios
/views -- vistas para el modulo comentarios
/css
/img
commentModule.js -- Modulo principal del modulo Comentarios
...
...
INDEX.html

Dentro de cada uno de estos archivos, definimos nuestros módulos, para el módulo Login, las definiciones son :

1
2
3
4
5
6
7
/app/modules/login/js/controllers.js
angular.module('mainApp.login.controllers',[]);
/app/modules/login/js/directives.js
angular.module('mainApp.login.directives',[]);
/app/modules/login/loginModule.js

angular.module('loginModule',['mainApp.login.controllers','mainApp.login.directives']);

De igual forma para el módulo de comentarios la definición es como sigue:

1
2
3
4
5
6
/app/modules/comment/js/controllers.js
angular.module('mainApp.comment.controllers',[]);
/app/modules/comment/js/directives.js
angular.module('mainApp.comment.directives',[]);
/app/modules/comment/loginModule.js
angular.module('commentModule',['mainApp.comment.controllers','mainApp.comment.directives']);

Finalmente definimos el módulo principal de la forma:

1
angular.module('mainApp',['loginModule','commentModule']);

Por último dentro de nuestro index.html configuramos la aplicación de AngularJS escribiendo el atributo ng-app=’mainApp’.

 

 

Te Puede Interesar

AngularJs, o el arte de extender HTML para desarrollar Single-Page Applications

 

(Visited 272 times, 1 visits today)