¡Esta es una revisión vieja del documento!
En este tema vamos a ver el servicio de factory
. La principal diferencia es que al método factory
le pasamos ahora una función para que ésta retorne ahora el valor del servicio. Es decir que tenemos una función JavaScript que actúa como factoría, retornando la propia función de factoría el valor del servicio.
Para que se entienda vamos a ver los ejemplos que teníamos con el value
ahora como un factory
.
var app=angular.module("app",[]); app.factory("idioma",function() { return "es-es"; }); app.factory("matematicas_simples",function() { return { sumar:function(a,b) { return a+b; }, restar:function(a,b) { return a-b; } } }); app.factory("radio",function() { return 10; }); app.factory("area",function() { return function(radio) { return 3.1416*radio*radio; } }); app.controller("PruebaController",["$scope","idioma","matematicas_simples","radio","area",function($scope,idioma,matematicas_simples,radio,area) { $scope.idioma=idioma; $scope.suma=matematicas_simples.sumar(3,6); $scope.area=area(radio); }]);
sumar
y restar
. Al ser un factory
ahora le pasamos la función anónima de factoría que retorna el objeto JavaScript.value
o factory
, etc.
Al igual que en el service
se podían inyectar dependencias en el constructor , en un factory
se pueden inyectar dependencias en la función de factoría.
Vamos a hacer el ejemplo del tema anterior del service
con la clase Rectangulo
usando un servicio:
var app=angular.module("app",[]); app.value("tamanyoInicialRectangulo",{ ancho:2, alto:3 }); function Rectangulo(tamanyoInicial) { this.ancho=tamanyoInicial.ancho; this.alto=tamanyoInicial.alto; this.setAncho=function(ancho) { this.ancho=ancho; } this.setAlto=function(alto) { this.alto=alto; } this.getArea=function() { return this.ancho * this.alto; } } app.factory("rectangulo",['tamanyoInicialRectangulo',function(tamanyoInicialRectangulo) { var rectangulo=new Rectangulo(tamanyoInicialRectangulo); return rectangulo; }]); app.controller("PruebaController",["$scope","rectangulo",function($scope,rectangulo) { $scope.area=rectangulo.getArea(); }]);
tamanyoInicialRectangulo
simplemente añadiendo el array con el nombre y poniendo la variable como argumento de la función.rectangulo
. Vemos como le estamos pasando al constructor, el valor que inyectamos a la función.
Vamos a explicar ahora un ejemplo en el que necesitamos la función factory ya que la creación del valor del servicio va a ser un poco compleja.
Vamos a suponer que necesitamos enviar el hash de una contraseña a un servidor. Vamos a tener un servicio de AngularJS llamado hash
que es una función. Esta función aceptará como parámetro un String y nos retornará el hash en formato Base64. P
enos retorne ro queremos que este servicio sea reutilizable por lo que va a soportar varios tipos de funciones de Hash: MD5, SHA1, SHA2-256 y SHA-2-512.
CryptoJS.MD5
CryptoJS.SHA1
Para configurar el servicio es necesario crear un value
llamado algoritmo
con el algoritmo que queremos usar.
app.value("algoritmo","SHA-1");Es este caso hemos configurado el algoritmo para que sea “SHA-1”.
Gastar el servicio hash
es tan sencillo como pasar el String y nos retorna otro.
app.controller("PruebaController",["$scope","hash",function($scope,hash) { $scope.password="s3cret"; $scope.getHash=function(message) { var hashResult=hash(message); return hashResult; } }]);
hash
.$scope
una función llamada gatHash
que acepta un String como parámetro y retorna el resultado de llamar a la función de Hash.El código HTML es el siguiente:
<!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> <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/md5.js"></script> <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js"></script> <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha256.js"></script> <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha512.js"></script> <script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js"></script> </head> <body ng-controller="PruebaController"> Contraseña:<input ng-model="password" /> <br> El hash de la contraseña es: <br> {{getHash(password)}} </body> </html>
<input>
para que el usuario escriba la contraseña.getHash
para que muestre el hash
Ahora viene la parte interesante, tenemos que crear un servicio mediante un factory que según el valor del value
“algoritmo” utilice una función de Hash u otra pero además queremos que el resultado de llamar a dicha función siempre esté codificado en Base64.
Esta es la típica pregunta que aparece siempre en los foros de AngularJS y la respuesta es bastante sencilla. Realmente da igual cual uses porque todos acaban siendo un provider
para AngularJS. Pero aun así ¿cual es mas recomendable?
service
: Solo tendrás que pasarle el nombre de la clase y ya está.value
: Solo tendrás que pasarle ese valor y ya está.factory
: Es lo mas complejo de usar así que debería ser siempre la última opción.
En el siguiente tema por fin veremos el provider el cual tiene una funcionalidad extra al factory
que si la necesitamos hará que debamos usarlo.
constant
ya que éste es distinto a los 3 anteriores 1) ya que permite ser inyectado en un bloque config y en un provider
cosa que ninguno de los 3 anteriores permite, por lo que si necesitamos esa funcionalidad deberemos usar obligatoriamente constant
.