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 13:26]
admin [value vs service vs 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.
  
 {{url>​http://​embed.plnkr.co/​7Xl1Th}} {{url>​http://​embed.plnkr.co/​7Xl1Th}}
  
 +===== La necesidad del factory =====
 +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. 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'': ​Lo mas complejo ​es usar una función factoría ​así que siempre ​debería ser 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> 
 +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>​
 ===== 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.1406719609.txt.gz · Última modificación: 2014/07/30 13:26 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