Diferencias

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

Enlace a la vista de comparación

unidades:03_servicios:07_service [2014/07/25 16:05]
admin creado
unidades:03_servicios:07_service [2014/08/29 21:48] (actual)
admin
Línea 1: Línea 1:
 ====== 3.7 service ====== ====== 3.7 service ======
 +Hemos visto por ahora 2 tipos de servicio , las ''​constant''​ y los ''​value''​. En ambos casos le pasábamos directamente el valor que debía tener el servicio. Con el tipo ''​service''​ (( que en este tema no referimos al tipo concreto ''​service''​ y no a los servicios en general )) le debemos pasar una //clase// ((Es una función que actúa como constructor)) JavaScript y será AngularJS el que cree internamente una instancia de la clase.
  
 +Lo veremos mas claro con el siguiente ejemplo:
 +<sxh js;​title;​script.js;​highlight:​ [3,20];>
 +var app=angular.module("​app",​[]);​
 +
 +function Rectangulo() {
 +  this.ancho=0;​
 +  this.alto=0;​
 +
 +  this.setAncho=function(ancho) {
 +    this.ancho=ancho;​
 +  }
 +  ​
 +  this.setAlto=function(alto) {
 +    this.alto=alto;​
 +  }  ​
 +  ​
 +  this.getArea=function() {
 +    return this.ancho * this.alto;
 +  }
 +}
 +
 +app.service("​rectangulo",​Rectangulo);​
 +
 +
 +app.controller("​PruebaController",​["​$scope","​rectangulo",​function($scope,​rectangulo) {
 +  rectangulo.setAncho(3);​
 +  rectangulo.setAlto(6);​
 +  ​
 +  $scope.area=rectangulo.getArea();​
 +}]);
 +</​sxh>​
 +
 +  * Línea 3: Aquí hemos definido la función JavaScript con el constructor de nuestra clase llamada "​Rectangulo"​.
 +  * Línea 20: Llamamos al método ''​service''​ y le pasamos como segundo parámetro la función con el constructor de la clase "​Rectangulo"​.
 +
 +===== Inyectando el constructor =====
 +Una funcionalidad que permite AngularJS es que le podamos inyectar servicios en el propio constructor.
 +
 +En el ejemplo anterior veíamos que el ancho y alto inicial era 0 , pero es un problema que los valores iniciales están //grabados a fuego// en el interior de la clase. Es mucho mas interesante que se puedan incluir en el constructor para que podamos elegir los que queramos.
 +
 +Así que la clase quedará de la siguiente forma:
 +<sxh js; highlight: [1,​2,​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;
 +  }
 +}
 +</​sxh>​
 +
 +  * Línea 1: Ahora el constructor acepta como parámetro un objeto con las propiedades ''​ancho''​ y ''​alto''​.
 +  * Línea 2: Se asigna como ancho inicial el valor de la propiedad ''​tamanyoInicial.ancho''​
 +  * Línea 3: Se asigna como alto inicial el valor de la propiedad ''​tamanyoInicial.alto''​
 +
 +Lo siguiente es hacer que haya un servicio ''​value''​ que contenga el tamaño inicial del rectángulo.
 +<sxh js>
 +app.value("​tamanyoInicialRectangulo",​{
 +  ancho:2,
 +  alto:3
 +});
 +</​sxh> ​
 +
 +Y ahora nos queda inyectar el ''​value''​ "​tamanyoInicialRectangulo"​ en el constructor de "​Rectangulo"​ y AngularJS por suerte ya tiene esa funcionalidad programada ((A mí me recuerda a Spring que también permite inyectar dependencias en los constructores)).
 +<sxh js>
 +app.service("​cuadrado",​['​tamanyoInicialRectangulo',​Cuadrado]);​
 +</​sxh>​
 +Vemos que junto al nombre del constructor que es ''​Cuadrado''​ hemos incluido el típico array de AngularJS con el nombre de los servicios a inyectar, que en nuestro caso es el ''​value''​ llamado ''​tamanyoInicialRectangulo''​
 +
 +El ejemplo completo quedaría de la siguiente forma:
 +<sxh js>
 +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.service("​rectangulo",​['​tamanyoInicialRectangulo',​Rectangulo]);​
 +
 +
 +app.controller("​PruebaController",​["​$scope","​rectangulo",​function($scope,​rectangulo) {
 +  $scope.area=rectangulo.getArea();​
 +}]);
 +</​sxh>​
 +
 +<note tip>
 +Hay que hacer notar que el nombre del ''​value''​ que se inyecta se llama "​tamanyoInicialRectangulo"​ mientras que el parámetro del constructor se llama "​tamanyoInicial"​. Es decir que tienen nombres distintos. No hay problema en ello ya que una vez inyectado el valor da igual el nombre del parámetro del constructor.
 +
 +Si no hubiéramos usado el array sí que se deberían de haber llamado igual , por lo que éste es un motivo más para usar siempre el array.
 +</​note>​
 +
 +===== Service vs value =====
 +Ahora, ¿qué hemos ganado usando un ''​service''​ en vez de un ''​value''​ cuando el valor es una objeto de una clase? Si no necesitamos inyección de dependencias en el constructor la verdad es que no hemos ganado mucho.
 +
 +El ejemplo inicial se podría haber hecho como un ''​value''​ de la siguiente forma:
 +
 +<sxh js;​title;​script.js;​highlight:​ [18];>
 +var app=angular.module("​app",​[]);​
 +
 +function Rectangulo() {
 +
 +  this.setAncho=function(ancho) {
 +    this.ancho=ancho;​
 +  }
 +  ​
 +  this.setAlto=function(alto) {
 +    this.alto=alto;​
 +  }  ​
 +  ​
 +  this.getArea=function() {
 +    return this.ancho * this.alto;
 +  }
 +}
 +
 +app.value("​rectangulo",​new Rectangulo());​
 +
 +
 +app.controller("​PruebaController",​["​$scope","​rectangulo",​function($scope,​rectangulo) {
 +  rectangulo.setAncho(3);​
 +  rectangulo.setAlto(6);​
 +  ​
 +  $scope.area=rectangulo.getArea();​
 +}]);
 +</​sxh>​
 +
 +  * Línea 18: Le pasamos directamente el objeto de la clase en vez de que internamente sea AngularJS el que cree el objeto.
 +
 +Realmente no hay mucha diferencia ya que como veremos mas adelante, tanto los [[unidades:​03_servicios:​06_value|value]] como los [[unidades:​03_servicios:​07_service|service]] como los [[unidades:​03_servicios:​08_factory|factory]] son solamente //azucar sintáctico//​ respecto a los [[unidades:​03_servicios:​09_provider|provider]]. Es decir , internamente para AngularJS son únicamente un [[unidades:​03_servicios:​09_provider|provider]] pero al ser los [[unidades:​03_servicios:​09_provider|provider]] un poco complejos de programar se han creado estas funciones para simplificar su uso. 
 +
 +Pero aun así, yo veo una ventaja de un ''​service''​ sobre un ''​value''​ cuando es un objeto de una clase. Si un servicio nunca se va a usar , AngularJS no lo inicializará por lo tanto usando un ''​service'',​ nos podríamos ahorrar el gasto de crear la instancia si no llegara a usarse o al menos retrasarlo hasta que se use, mientras que con un ''​value''​ siempre se crearía. ​
 +
 +Esto que puede parecer poca cosa, podría implicar gran gasto de recursos en grandes aplicaciones en las que hay gran cantidad de servicios y también debemos añadir todos los servicios que crean las librerías de terceros que usemos.
 +
 +<note tip>
 +Es preferible usar un ''​service''​ en vez de un ''​value''​ cuando es una instancia de una clase ya que:
 +  * Nos podemos ahorrar la creación de la instancia o al menos retrasarla hasta que sea necesaria
 +  * Permite inyectar dependencias en el constructor
 +</​note>​
 +
 +===== Ejemplo =====
 +{{url>​http://​embed.plnkr.co/​9RJnmH}}
 +===== Referencias =====
 +  * [[https://​docs.angularjs.org/​guide/​providers#​service-recipe|/​ Developer Guide / Providers / Service]]
unidades/03_servicios/07_service.1406297153.txt.gz · Última modificación: 2014/07/25 16:05 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