Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

unidades:03_servicios:08_factory [2014/07/30 14:08]
admin [La necesidad del factory]
unidades:03_servicios:08_factory [2014/09/22 18:57] (actual)
admin
Línea 1: Línea 1:
 ====== 3.8 factory ====== ====== 3.8 factory ======
-En este tema vamos a ver el servicio de ''​factory''​. La principal diferencia ​ahora 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. ​+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''​.+Para que se entiendavamos a ver los ejemplos que teníamos con el ''​value''​ ahora como un ''​factory''​.
  
 <sxh js;​highlight:​ [3,​7,​18,​22,​28];>​ <sxh js;​highlight:​ [3,​7,​18,​22,​28];>​
Línea 43: Línea 43:
   * Líneas 7-16: El valor del servicio "​matematicas_simples"​ era un objeto javaScript con los métodos ''​sumar''​ y ''​restar''​. Al ser un ''​factory''​ ahora le pasamos la función anónima de factoría que retorna el objeto JavaScript.   * Líneas 7-16: El valor del servicio "​matematicas_simples"​ era un objeto javaScript con los métodos ''​sumar''​ y ''​restar''​. Al ser un ''​factory''​ ahora le pasamos la función anónima de factoría que retorna el objeto JavaScript.
   * Líneas 18-20: En el servicio de "​radio"​ , la función anónima retorna el valor del servicio que es un 10.   * Líneas 18-20: En el servicio de "​radio"​ , la función anónima retorna el valor del servicio que es un 10.
-  * Líneas 22-26: El valor del servicio "​area"​ es una función que calcula el área, por lo tanto la función anónima debe retorna ​la función que calcula el área. Es decir es una función que retorna otra función.+  * Líneas 22-26: El valor del servicio "​area"​ es una función que calcula el área, por lo tanto la función anónima debe retornar ​la función que calcula el área. Es decir es una función que retorna otra función.
   * Línea 28: Por último vemos que en el controlador se usan igual los servicios independientemente de si son ''​value''​ o ''​factory'',​ etc.   * Línea 28: Por último vemos que en el controlador se usan igual los servicios independientemente de si son ''​value''​ o ''​factory'',​ etc.
  
Línea 90: Línea 90:
  
   * Línea 25: Como ya hemos visto en las funciones de los controladores,​ inyectamos la dependencia ''​tamanyoInicialRectangulo''​ simplemente añadiendo el array con el nombre y poniendo la variable como argumento de la función.   * Línea 25: Como ya hemos visto en las funciones de los controladores,​ inyectamos la dependencia ''​tamanyoInicialRectangulo''​ simplemente añadiendo el array con el nombre y poniendo la variable como argumento de la función.
-  * Línea 26: Aquí es cuando se ve realmente ​que es una función de factoría. Estamos creando el valor del servicio al crear el objeto ''​rectangulo''​. Vemos como le estamos pasando al constructor,​ el valor que inyectamos a la función.+  * Línea 26: Aquí es cuando se ve realmente ​qué es una función de factoría. Estamos creando el valor del servicio al crear el objeto ''​rectangulo''​. Vemos cómo le estamos pasando al constructor,​ el valor que inyectamos a la función.
   * Línea 28: como ya sabemos se debe retornar el valor del servicio.   * Línea 28: como ya sabemos se debe retornar el valor del servicio.
  
Línea 96: Línea 96:
  
 ===== La necesidad del factory ===== ===== La necesidad del factory =====
-Vamos a explicar ahora un ejemplo en el que necesitamos la función factory ​ ​((Realmente con un service también se podría hacer pero ésto es modo de ejemplo)).+Vamos a explicar ahora un ejemplo en el que necesitamos la función factory ​ya que la creación del valor del servicio va ser un poco compleja.
  
-Vamos a suponer que necesitamos enviar el hash de una contraseña a un servidor. El servidor ​acepta ​+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. Pero 
 +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. 
 + 
 +<note tip> 
 +Para implementar las distintas funciones de Hash vamos a usar la librería [[https://​code.google.com/​p/​crypto-js/​|CryptoJS]]. 
 +Las distintas funciones de Hash que tiene son: 
 +  * [[https://​code.google.com/​p/​crypto-js/#​MD5]]:​ ''​CryptoJS.MD5''​ 
 +  * [[https://​code.google.com/​p/​crypto-js/#​SHA-1]]:​ ''​CryptoJS.SHA1''​ 
 +  * [[https://​code.google.com/​p/​crypto-js/#​SHA-2]]:​ ''​CryptoJS.SHA256''​ y ''​CryptoJS.SHA512''​ 
 + 
 +y la forma de generar el resultado en Base64 es mediante [[https://​code.google.com/​p/​crypto-js/#​The_Hasher_Output|The Hasher Output]] usando la función: ''​hash.toString(CryptoJS.enc.Base64)''​ 
 + 
 +Un ejemplo de todo ello es el siguiente:​ 
 + 
 +<sxh js> 
 +<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/​components/​enc-base64-min.js"></​script>​ 
 +<​script>​ 
 +    var hash = CryptoJS.SHA256("​Message"​);​ 
 + 
 +    alert(hash.toString(CryptoJS.enc.Base64));​ // L3dmip37+NWEi57rSnFFypTG7ZI25Kdz9tyvpRMrL5E= 
 +</​script>​ 
 +</​sxh>​ 
 + 
 +</​note>​ 
 + 
 + 
 +Para configurar el servicio es necesario crear un ''​value''​ llamado ''​algoritmo''​ con el algoritmo que queremos usar. 
 +<sxh js> 
 +app.value("​algoritmo","​SHA-1"​);​ 
 +</​sxh>​  
 +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. 
 +<sxh js;​highlight:​ [1,​3];>​ 
 +app.controller("​PruebaController",​["​$scope","​hash",​function($scope,​hash) { 
 +  $scope.password="​s3cret";​ 
 +  $scope.getHash=function(message) { 
 +    var hashResult=hash(message);​ 
 +    return hashResult;​ 
 +  } 
 +}]); 
 +</​sxh>​ 
 + 
 +  * Línea 1: En el controlador inyectamos la función de hash llamada ''​hash''​. 
 +  * Línea 3: Se ha creado en el ''​$scope''​ una función llamada ''​getHash''​ 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:​ 
 +<sxh html;​title:​index.html;​highlight:​ [7,​8,​9,​10,​11,​15,​19];>​ 
 +<​!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&​ntilde;​a:<​input ng-model="​password"​ /> 
 +    <​br>​ 
 +    El hash de la contrase&​ntilde;​a es: 
 +    <​br>​ 
 +    {{getHash(password)}} 
 +  </​body>​ 
 +</​html>​ 
 +</​sxh>​ 
 + 
 +  * Líneas 7-11: Cargamos la librería con los 4 algoritmos de Hash a usar y la codificación en Base64. 
 +  * Línea 15: Tenemos un tag ''<​input>''​ para que el usuario escriba la contraseña. 
 +  * Línea 18: Se llama a la función ''​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. 
 + 
 +==== El factory ==== 
 +Como ya hemos dicho nuestro servicio llamado ''​hash''​ nos retornará una función que realiza el hash pero con el algoritmo configurable y el resultado codificado en Base64. 
 + 
 +Veamos como queda la función: 
 +<sxh js;;​highlight:​ [1,​4,​16,​17,​19,​24];>​ 
 +app.factory("​hash",​['​algoritmo',​function(algoritmo) { 
 +  var hashFunction;​ 
 +   
 +  if (algoritmo==="​MD5"​) { 
 +    hashFunction=CryptoJS.MD5;​ 
 +  } else  if (algoritmo==="​SHA-1"​) { 
 +    hashFunction=CryptoJS.SHA1;​ 
 +  } else  if (algoritmo==="​SHA-2-256"​) { 
 +    hashFunction=CryptoJS.SHA256;​ 
 +  } else  if (algoritmo==="​SHA-2-512"​) { 
 +    hashFunction=CryptoJS.SHA512;​ 
 +  } else { 
 +    throw Error("​El tipo de algoritmo no es válido:"​+algoritmo);​ 
 +  } 
 +   
 +  var hash=function(message) { 
 +    var objHashResult=hashFunction(message);​ 
 +     
 +    var strHashResult=objHashResult.toString(CryptoJS.enc.Base64);​ 
 +     
 +    return strHashResult;​ 
 +  } 
 +   
 +  return hash; 
 +   
 +}]); 
 +</​sxh>​ 
 +  * Línea 1: Inyectamos el valor del algoritmo a usar. 
 +  * Líneas 4 a 14: En función del valor de ''​algoritmo''​ usamos una función u otra de Hash. Pero ésta no va a ser la verdadera función que vamos a retornar ya que el resultado de esta función es un Objeto pero nosotros queremos que sea un String codificado en Base64. 
 +  * Línea 16: Ahora creamos la verdadera función , la cual es la que retornará el servicio.Y que es la que realmente será llamada desde el controlador. Vemos que acepta ​como único argumento el mensaje. 
 +  * Línea 17: Llamamos a la función que verdaderamente genera el Hash 
 +  * Línea 19: Ahora transformamos el objeto en un String en Base64 llamando al método ''​toString''​ 
 +  * Línea 24: Aquí es donde la función factory retorna la función de hash que hemos creado. 
 + 
 + 
 +Si has llegado hasta aquí y lo has entendido todo: ¡Felicidades! pero sino , tampoco pasa nada. Era un ejemplo para ver la potencia de las funciones factory y lo útiles que pueden llegar a ser. Así que lo realmente útil siempre es el ''​factory''​ ya que nos permite crear cualquier tipo de valor de un servicio por muy complejo que sea. 
 + 
 + 
 +{{url>​http://​embed.plnkr.co/​XLCPo2}}
 ===== value vs service vs factory ===== ===== value vs service vs factory =====
-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?​+Esta es la típica pregunta que aparece siempre en los foros de AngularJS y la respuesta es bastante sencilla. Realmente da igual cuál uses porque todos acaban siendo un ''​provider''​ para AngularJS. Pero aun así ¿cuál ​es más recomendable?​
  
-  - Si tienes una clase de la que es necesario crear una instancia mejor usa un ''​service'': ​Solo tendrás que pasarle el nombre de la clase y ya está. +  - Si tienes una clase de la que es necesario crear una instancia mejor usa un ''​service'': ​Sólo tendrás que pasarle el nombre de la clase y ya está. 
-  - Si tienes directamente el valor mejor usar el ''​value'':​ Solo tendrás que pasarle ese valor y ya está. +  - Si tienes directamente el valormejor usar el ''​value'':​ Solo tendrás que pasarle ese valor y ya está. 
-  - Si no queda mas remedio entonces ​usar el ''​factory'':​ Es lo mas complejo de usar así que debería ser siempre la última opción.+  - Si no queda más remedio entonces ​usa el ''​factory'':​ Es lo más complejo de usar así que debería ser siempre la última opción.
  
-En el siguiente tema por fin veremos el [[unidades:​03_servicios:​09_provider|provider]] el cual tiene una funcionalidad extra al ''​factory''​ que si la necesitamos ​hará que debamos ​usarlo.+En el siguiente tema por fin veremos el [[unidades:​03_servicios:​09_provider|provider]] el cual tiene una funcionalidad extra al ''​factory''​ que si la necesitamos ​estaremos obligados a usarlo.
  
  
 <note tip> <note tip>
-En esta discusión no hemos hablado del ''​constant''​ ya que éste es distinto a los 3 anteriores ((''​value''​ , ''​service''​ y ''​factory''​)) ​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''​.+En esta discusión no hemos hablado del ''​constant''​ ya que éste es distinto a los 3 anteriores ((''​value''​ , ''​service''​ y ''​factory''​)) ​puesto ​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''​.
 </​note>​ </​note>​
 ===== Referencias ===== ===== Referencias =====
   * [[https://​docs.angularjs.org/​guide/​providers#​factory-recipe|/​ Developer Guide / Providers / Factory]]   * [[https://​docs.angularjs.org/​guide/​providers#​factory-recipe|/​ Developer Guide / Providers / Factory]]
- 
unidades/03_servicios/08_factory.1406722136.txt.gz · Última modificación: 2014/07/30 14:08 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