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 17:53]
admin
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.
  
-Como siempre hacemos ​veamos ​un ejemplo:+<note tip> 
 +Un provider está compuesto de 2 partes: 
 +  * 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 
 +</​note>​ 
 + 
 + 
 +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 46: 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 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 ​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.
-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.+
  
 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.
  
-<sxh js;highlight: [1,2]>+<sxh js>
 app.config(["​hashProvider",​function(hashProvider) { app.config(["​hashProvider",​function(hashProvider) {
   hashProvider.setAlgoritmo("​SHA-1"​);​   hashProvider.setAlgoritmo("​SHA-1"​);​
 }]); }]);
 </​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 68: 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>​
  
-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.+Una vez configurado el provider en el bloque config ya podremos inyectar el servicio donde queramos , en un controlador,​ en otro servicioen un bloque run, etc.
  
-<note tip> +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''​)). 
-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''​). ​+
  
-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.
-</​note>​+
  
-<note tip> 
-Ahora es tiempo de que vuelvas a repasar el tema [[unidades:​03_servicios:​04_tiposservicios]] y ver si ahora lo entiendes todo perfectamente. 
-</​note>​ 
  
-===== Inyectando dependencias ​en el provider ​===== + 
-<note tip> +===== Inyectando dependencias ===== 
-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:+Ya hemos dicho que un provider está definido por 2 funciones:​ 
 +  * 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//.
  
 +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 =====
 +Ahora es hora de que vuelvas a repasar el tema [[unidades:​03_servicios:​04_tiposservicios]] y ver si ahora lo entiendes todo perfectamente.
 +
 +
 +<note important>​
 +Repasa el tema [[unidades:​03_servicios:​04_tiposservicios]]
 </​note>​ </​note>​
 +===== Referencias =====
 +  * [[https://​docs.angularjs.org/​guide/​providers#​provider-recipe|/​ Developer Guide / Providers / Provider Recipe]]
unidades/03_servicios/09_provider.1406735622.txt.gz · Última modificación: 2014/07/30 17:53 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