Diferencias

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

Enlace a la vista de comparación

unidades:03_servicios:09_provider [2014/07/30 18:17]
admin [Configurando el provider]
unidades:03_servicios:09_provider [2014/09/22 19:02] (actual)
admin [3.9 provider]
Línea 2: Línea 2:
 Por fin llegamos al ''​provider''​ el último de los tipos de servicios en AngularJS y con el que espero que se entiendan por fin las diferencias entre todos ellos. Por fin llegamos al ''​provider''​ el último de los tipos de servicios en AngularJS y con el que espero que se entiendan por fin las diferencias entre todos ellos.
  
-Un ''​provider''​ es como un ''​factory'' ​solo que permite que se configure antes de crear el valor del servicio. En el tema anterior ​hemos visto el ejemplo del servicio de ''​hash''​ que se configuraba a través de un ''​value''​ llamado ''​algoritmo''​. Aunque el ejemplo ​ha funcionado, la verdad es que es un poco chapucero ya que aparentemente no hay relación entre ''​algoritmo''​ y ''​hash''​ . La relación entre ambos queda poco orientada al objeto. El ''​provider''​ viene en nuestra ayuda creando un objeto previo que permite configurar el factory antes de que cree el valor del servicio. Este nuevo objeto se llama **Provider** y en un bloque ''​config''​ podremos acceder a él para poder configurar nuestro servicio.+Un ''​provider''​ es como un ''​factory'' ​pero permite que se configure antes de crear el valor del servicio. En el tema anterior ​vimos el ejemplo del servicio de ''​hash''​ que se configuraba a través de un ''​value''​ llamado ''​algoritmo''​. Aunque el ejemplo ​ ​funciona, la verdad es que es un poco chapucero ya que aparentemente no hay relación entre ''​algoritmo''​ y ''​hash''​ . La relación entre ambos queda poco orientada al objeto. El ''​provider''​ viene en nuestra ayuda creando un objeto previo que permite configurar el factory antes de que cree el valor del servicio. Este nuevo objeto se llama **Provider** y en un bloque ''​config''​ podremos acceder a él para poder configurar nuestro servicio.
  
 <note tip> <note tip>
 Un provider está compuesto de 2 partes: Un provider está compuesto de 2 partes:
-  * El provider que es una clase JavaScript de la que se crea un único objeto , el cual se permite llamar en un bloque config antes de que se llame al factory-provider y asi poder configurar el factory-provider. +  * El provider que es una clase JavaScript de la que se crea un único objeto , el cual permite llamar en un bloque config antes de que se llame al factory-provider y asi poder configurar el factory-provider. 
-  * El factory-provider el cual crea el valor del servicio. Es prácticamente como la función factory del tema anterior y la llamamos factory-provider+  * El factory-providerel cual crea el valor del servicio. Es prácticamente como la función factory del tema anterior y la llamamos factory-provider
 </​note>​ </​note>​
  
  
-Como siempre hacemos, ​veamos ​un ejemplo:+Como siempre hacemos, ​vamos a ver un ejemplo:
 <sxh js;​highlight:​ [1,​2,​4,​8,​35];>​ <sxh js;​highlight:​ [1,​2,​4,​8,​35];>​
 function HashProvider() { function HashProvider() {
Línea 53: Línea 53:
   * Línea 2: Se define la propiedad privada ''​algoritmo''​ la cual contendrá el algoritmo a usar.   * Línea 2: Se define la propiedad privada ''​algoritmo''​ la cual contendrá el algoritmo a usar.
   * Línea 4: Método público que nos permite establecer el algoritmo a usar antes de crear la función de hash.   * Línea 4: Método público que nos permite establecer el algoritmo a usar antes de crear la función de hash.
-  * Linea 8: Método público que es realmente el factory que creará el valor ser servicio.En toda clase Provider es obligatorio que exista este método público llamado ''​$get''​. Es una obligación que impone AngularJS para que él sepa cual es el método factory. Podemos ver que este método es exactamente igual al del tema anterior de [[unidades:​03_servicios:​08_factory|factory]] excepto que ahora usa la propiedad privada ''​_algoritmo''​ en vez de llamar al servicio ''​algoritmo''​. ​Este es el método que en el tema [[unidades:​03_servicios:​04_tiposservicios]] llamábamos "​factory-provider"​.+  * Linea 8: Método público que es realmente el factory que creará el valor del servicio.En toda clase Provider es obligatorio que exista este método público llamado ''​$get''​. Es una obligación que impone AngularJS para que él sepa cuál es el método factory. Podemos ver que este método es exactamente igual al del tema anterior de [[unidades:​03_servicios:​08_factory|factory]] excepto que ahora usa la propiedad privada ''​_algoritmo''​ en vez de llamar al servicio ''​algoritmo''​. ​Éste es el método que en el tema [[unidades:​03_servicios:​04_tiposservicios]] llamábamos "​factory-provider"​.
   * Línea 35: Definimos el ''​provider''​ con el nombre ''​hash''​ y le pasamos como argumento el nombre de la clase ''​HashProvider''​.   * Línea 35: Definimos el ''​provider''​ con el nombre ''​hash''​ y le pasamos como argumento el nombre de la clase ''​HashProvider''​.
  
-Resumiendo hemos creado una clase JavaScript llamada ''​HashProvider''​ con distintas propiedades y métodos ((en nuestro ejemplo ​solo está la propiedad privada ''​_algoritmo''​ y el método público ''​setAlgoritmo''​ )) que permitirán configurar el factory-provider. El factory-provider es la función ''​$get''​ del provider. Por lo tanto dicha función hará uso de las propiedades que se ha definido en la clase ((en nuestro ejemplo hace uso de la propiedad ''​algoritmo''​)).+Resumiendohemos creado una clase JavaScript llamada ''​HashProvider''​ con distintas propiedades y métodos ((en nuestro ejemplo ​sólo está la propiedad privada ''​_algoritmo''​ y el método público ''​setAlgoritmo''​ )) que permitirán configurar el factory-provider. El factory-provider es la función ''​$get''​ del provider. Por lo tanto dicha función hará uso de las propiedades que se han definido en la clase ((en nuestro ejemplo hace uso de la propiedad ''​algoritmo''​)).
  
 ===== Configurando el provider ===== ===== Configurando el provider =====
-Ya tenemos definido el provider pero ahora es necesario poder configurarlo para establecer ​cual es el algoritmo a usar. Los [[unidades:​03_servicios:​04_tiposservicios&#​bloque_config|bloques config]] son los únicos que permiten configurar el provider.+Ya tenemos definido el provider pero ahora es necesario poder configurarlo para establecer ​cuál es el algoritmo a usar. Los [[unidades:​03_servicios:​04_tiposservicios&#​bloque_config|bloques config]] son los únicos que permiten configurar el provider.
  
 En el bloque config será necesario inyectar el provider , **no el factory-provider** para poder configurarlo. En el bloque config será necesario inyectar el provider , **no el factory-provider** para poder configurarlo.
Línea 68: Línea 68:
 }]); }]);
 </​sxh>​ </​sxh>​
-  * Línea 1: Inyectamos el provider en la función de config. ​Hay que fijarse ​que AngularJS nos obliga en este caso a llamar al proviver ​"​hashProvider"​ . Es decir que al nombre de nuestro servicio se añade la palabra "​Provider"​ de esa forma le estamos diciendo que queremos el objeto provider para configurarlo y no el objeto final del servicio.+  * Línea 1: Inyectamos el provider en la función de config. ​Nótese ​que AngularJS nos obliga en este caso a llamar al provider ​"​hashProvider"​ . Es decir que al nombre de nuestro servicio se añade la palabra "​Provider" ​de esa forma le estamos diciendo que queremos el objeto provider para configurarlo y no el objeto final del servicio.
   * Línea 2: Ahora llamamos al método público del provider llamado ''​setAlgoritmo''​ para configurar el algoritmo.   * Línea 2: Ahora llamamos al método público del provider llamado ''​setAlgoritmo''​ para configurar el algoritmo.
  
Línea 74: Línea 74:
 Recuerda que al inyectar el provider en un bloque config hay que incluir en el nombre el sufijo "​Provider"​. Recuerda que al inyectar el provider en un bloque config hay que incluir en el nombre el sufijo "​Provider"​.
  
-Por ejemplo si el provider ​se llama "​login"​ ,al inyectarlo en un bloque config habrá que poner "​loginProvider"​+Por ejemplo si el servicio ​se llama "​login"​ ,al inyectarlo en un bloque config habrá que poner "​loginProvider"​
  
 </​note>​ </​note>​
Línea 80: Línea 80:
 Una vez configurado el provider en el bloque config ya podremos inyectar el servicio donde queramos , en un controlador,​ en otro servicio, en un bloque run, etc. Una vez configurado el provider en el bloque config ya podremos inyectar el servicio donde queramos , en un controlador,​ en otro servicio, en un bloque run, etc.
  
-Volvamos ahora a repasar la diferencia entre los bloques config y los bloques run. Un bloque config ​solo existe para poder configurar un provider y ninguno de los servicios está aun creado ((A excepción de ''​constant''​)). ​+Volvamos ahora a repasar la diferencia entre los bloques config y los bloques run. Un bloque config ​sólo existe para poder configurar un provider y ninguno de los servicios está aún creado ((A excepción de ''​constant''​)). ​
  
-Mientras que en un bloque run todos los servicios ya está configurados y se pueden usar. Por ellos el bloque run es mas parecido a un método ''​Main''​ mientras que el bloque config es mas parecido a un trozo de código de preinicialización de la aplicación.+Mientras que en un bloque run todos los servicios ya está configurados y se pueden usar. Por ello el bloque run es más parecido a un método ''​Main''​ mientras que el bloque config es más parecido a un trozo de código de preinicialización de la aplicación.
  
  
  
 ===== Inyectando dependencias ===== ===== Inyectando dependencias =====
-<note tip> +Ya hemos dicho que un provider está definido por 2 funciones:​ 
-No vamos a poner un ejemplo aquí pero a la función de ''​$get''​ se le pueden ​seguir inyectando servicios quedando ​de la siguiente forma:+  * La función constructora de la clase que permite la configuración,​ que llamamos provider 
 +  * La función ​factory que crea el valor del servicio, que llamamos factory-provider. 
 + 
 +AngularJS nos permite en ambas funciones que podamos inyectar dependencias aunque en cada uno de ellos de tipos distintos. Veamos qué podemos inyectar en cada uno de ellos: 
 +  * provider: Podemos inyectar sólo ''​constant''​ y otros providers pero definidos en otros módulos. 
 +  * factory-provider:​ Podemos inyectar ''​constant'',​ ''​value'',​ ''​service'',​ ''​factory''​ y ''​factory-provider''​ 
 + 
 +Veamos ahora un pequeño ejemplo de ello: 
 +<sxh js;​highlight:​ [6,​7];>​ 
 +app.constant("​provincia","​Madrid"​);​ 
 +app.factory("​municipio",​function() { 
 +  return "​Mostoles";​ 
 +}); 
 + 
 +app.provider("​direccion",​['​provincia',​function(provincia) { 
 +  this.$get=['municipio',​function(municipio) { 
 +    return provincia+","​+municipio;​ 
 +  }] 
 +}]); 
 +</​sxh>​ 
 +  * Línea 6: Definimos un provider llamado "​direccion"​ e inyectamos la constante ''​provincia''​. 
 +  * Línea 7: En el factory-provider inyectamos el factory ''​municipio''​ 
 + 
 +El ejemplo no tiene mucho sentido pero se ha puesto simplemente para ver que se pueden ​inyectar dependencias en ambas funciones. 
 + 
 +Otra cosa interesante ​de este ejemplo es que en vez de crear la función del Provider aparte , se ha definido como una función anónima de JavaScript. Son cosas que permite el propio lenguaje y no tienen nada que ver con AngularJS. 
 + 
 +===== Mejorando la configuración ===== 
 +Aún nos queda un pequeño cambio por hacer para mejorar la arquitectura del ejemplo.Al configurar el provider hemos puesto directamente en el bloque config el algoritmo a usar: 
 <sxh js> <sxh js>
-this.$get=['​serv1','​serv2'​,function(serv1,serv2) { +app.config(["​hashProvider"​,function(hashProvider) { 
-}];+  hashProvider.setAlgoritmo("​SHA-1"​);​ 
 +}]);
 </​sxh>​ </​sxh>​
 +  * Línea 2: Tenemos el texto "​SHA-1"​ //a piñon//.
  
-</note>+Como todos sabemos no es buena idea poner texto fijos en el código, así que lo ideal es modificarlo añadiendo una constante de la siguiente forma: 
 + 
 +<sxh js> 
 +app.constant("​algoritmo","​SHA-1"​);​ 
 +app.config(["​hashProvider","​algoritmo",​function(hashProvider,​algoritmo) { 
 +  hashProvider.setAlgoritmo(algoritmo);​ 
 +}]); 
 +</​sxh>​ 
 +  * Línea 1: Creamos la constante con el valor del algoritmo, que en este caso es "​SHA-1"​. 
 +  * Línea 2: Inyectamos la constante en el bloque config 
 +  * Línea 3: Establecemos el algoritmo que debe usar el ''​provider''​ llamado ''​hash''​ con el valor de la constante. 
 + 
 +Pero, ¿no habíamos hecho todo ésto para evitar usar la constante?​!!!!!! Sí, y seguimos sin hacerlo. Lo que queríamos era que el ''​provider''​ no usara directamente la constante y sigue sin hacerlo. Esta nueva constante realmente formaría parte de nuestra aplicación y no del ''​provider'',​ así que lo que estamos mejorando es nuestra propia aplicación y no el ''​provider'',​ que gracias a ser un ''​provider''​ es perfectamente personalizable y no depende de ninguna constante. 
 +===== Ejemplo ===== 
 +Podemos ver ahora el ejemplo completo. 
 + 
 +<sxh html;​title:​index.html>​ 
 +<​!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>​ 
 + 
 +<sxh js;​title:​script.js>​ 
 +var app=angular.module("​app",​[]);​ 
 + 
 +app.constant("​algoritmo","​SHA-1"​);​ 
 + 
 + 
 +function HashProvider() { 
 +  var _algoritmo="";​ 
 +   
 +  this.setAlgoritmo=function(algoritmo) { 
 +    _algoritmo=algoritmo;​ 
 +  }; 
 +   
 +  this.$get=function() { 
 +    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; 
 +  } 
 +
 + 
 +app.provider("​hash",​HashProvider);​ 
 + 
 + 
 +app.config(["​hashProvider","​algoritmo",​function(hashProvider,​algoritmo) { 
 +  hashProvider.setAlgoritmo(algoritmo);​ 
 +}]); 
 + 
 +app.controller("​PruebaController",​["​$scope","​hash",​function($scope,​hash) { 
 +  $scope.password="​s3cret";​ 
 +  $scope.getHash=function(message) { 
 +    var hashResult=hash(message);​ 
 +    return hashResult;​ 
 +  } 
 +}]); 
 +</sxh>
  
  
 +{{url>​http://​embed.plnkr.co/​PUXsjE}}
 ===== Repasando los tipos de servicios ===== ===== Repasando los tipos de servicios =====
-Ahora es tiempo ​de que vuelvas a repasar el tema [[unidades:​03_servicios:​04_tiposservicios]] y ver si ahora lo entiendes todo perfectamente.+Ahora es hora de que vuelvas a repasar el tema [[unidades:​03_servicios:​04_tiposservicios]] y ver si ahora lo entiendes todo perfectamente.
  
  
unidades/03_servicios/09_provider.1406737056.txt.gz · Última modificación: 2014/07/30 18:17 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