Programación

Factorías (factory) en AngularJS

Qué son las factorías

Las factorías son como contenedores de código que podemos usar en nuestros sitios desarrollados con AngularJS. Son un tipo de servicio, «service» en Angular, con el que podemos implementar librerías de funciones o almacenar datos.

Cuando las usamos tienen la particularidad de devolvernos un dato, de cualquier tipo. Lo común es que nos devuelvan un objeto de Javascript donde podremos encontrar datos (propiedades) y operaciones (métodos). Con diferencia de los controladores, las factorías tienen la característica de ser instanciados una única vez dentro de las aplicaciones, por lo que no pierden su estado. Por tanto, son un buen candidato para almacenar datos en nuestra aplicación que queramos usar a lo largo de varios controladores, sin que se inicialicen de nuevo cuando se cambia de vista.

Angular consigue ese comportamiento usando el patrón «Singleton» que básicamente quiere decir que, cada vez que se necesite un objeto de ese tipo, se enviará la misma instancia de ese objeto en lugar de volver a instanciar un ejemplar.

Notas sobre los «services» en Angular

Los «services» en AngularJS incluyen tanto factorías como servicios. Más adelante veremos la diferencia. Lo que queremos mencionar ahora es que estos contenedores de código ya los hemos usado en diversas ocasiones y quizás podrás entender su utilidad mejor si analizamos cosas que ya conoces.

Por ejemplo, cuando estás haciendo Ajax, por los métodos que hemos conocido hasta el momento, usamos $http. Éste no es más que un service de Angular que engloba toda la funcionalidad necesaria para realizar solicitudes asíncronas a un servidor.

Por tanto, algo como Ajax, que se supone que puedes querer realizar a lo largo de tu aplicación en varias partes del código, se ha separado a un «servicio». Esto quiere decir que, cuando quieras hacer Ajax, tendrás que usar el código del «service» $http.

Los servicios y factorías que desees usar en tus controladores o módulos deberás inyectarlos como has visto hacer en diversas partes de nuestros ejemplos. No te preocupes si no lo recuerdas porque a continuación veremos ejemplos.

Ejemplo de factoría en AngularJS

Ahora nos vamos a poner manos a la obra creando nuestra primera factoría. Para ello vamos a continuar con el ejercicio que hemos visto en los artículos anteriores del Manual de AngularJS. Como recordarás, queremos implementar un sistema que nos memorice cierta información de nuestra aplicación a lo largo de diversas vistas.

Implementamos factorías con el método factory() que depende del módulo (objeto module) de nuestra aplicación.

Osea, como cualquier aplicación de Angular, lo primero crearás tu «module» principal:

angular.module("app", ["ngRoute"])

Y sobre el objeto que devuelve esa operación crearemos las factorías.

.factory("descargasFactory", function(){
    var descargasRealizadas = ["Manual de Javascript", "Manual de jQuery", "Manual de AngularJS"];

    var interfaz = {
        nombre: "Manolo",
        getDescargas: function(){
            return descargasRealizadas;
        },
        nuevaDescarga: function(descarga){
            descargasRealizadas.push(descarga);
        }
    }
    return interfaz;
})

Esta factoría se llama «descargasFactory». El nombre lo hemos definido en la llamada al método factory. Acuérdate de este nombre, pues luego lo tendrás que usar al inyectar la dependencia de esta factoría en tus controladores.

Ese código tiene una serie de detalles interesantes, desde el punto de vista de Angular y también desde el de Javascript en general. Estudiar el código anterior con detalle es suficiente para un único artículo, porque entran en juego diversos conceptos de la programación orientada a objetos en Javascript. De todos modos, te vamos a resumir un poco lo que encuentras.

Usar una factoría

Ahora podemos ver cómo usar la factoría que acabamos de realizar. El procedimiento es tan simple como, una vez definida, inyectarla en el controlador donde la queremos usar. Usamos el sistema de inyección de dependencias que ya conoces.

Al crear la función del controlador debemos definir un parámetro que se llame exactamente igual al nombre que le has dado en la factoría. En este caso el parámetro que inyectamos en el controlador se llama «descargasFactory» pues así habíamos llamado a la factoría al crearla.

Echa ahora un vistazo a un controlador que usa esta factoría.

.controller("appCtrl", function(descargasFactory){
    var vm = this;
    
    vm.nombre = descargasFactory.nombre;
    vm.descargas = descargasFactory.getDescargas();
    vm.funciones = {
        guardarNombre: function(){
            descargasFactory.nombre = vm.nombre;
        },
        agregarDescarga: function(){
            descargasFactory.nuevaDescarga(vm.nombreNuevaDescarga);
            vm.mensaje = "Descarga agregada";
        },
        borrarMensaje: function(){
            vm.mensaje = "";
        }
    }
});

Dentro de nuestro controlador la variable descargasFactory que recibimos como parámetro contiene todos los datos y funciones que hemos definido en la interfaz pública de nuestra factoría.

Por tanto:

– descargasFactory.nombre contendrá la propiedad «nombre» definida en la factory.
– descargasFactory.nuevaDescarga() o descargasFactory.getDescargas() serán llamadas a los métodos que habíamos definido en la factoría.

Creo que con todo esto queda explicado el trabajo con las factorías en AngularJS. Ahora faltaría un poco de tiempo por tu parte para poder ponerlo en práctica.

Salir de la versión móvil