Herramientas de usuario

Herramientas del sitio


unidades:03_servicios:10_ejemploseguro

Diferencias

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

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
unidades:03_servicios:10_ejemploseguro [2014/07/30 20:32] – adminunidades:03_servicios:10_ejemploseguro [2014/08/29 22:15] (actual) – admin
Línea 1: Línea 1:
 ====== 3.10 Ejemplo servicio ====== ====== 3.10 Ejemplo servicio ======
-En este tema retomamos ahora el ejemplo del seguro médico para añadir un ''provider''. +En este tema retornamos el ejemplo del seguro médico para añadir un ''provider''. 
  
-Al ver el servicio ''$http'' en el tema [[unidades:03_servicios:02_http]] vimos que no debía hacerse una llamada a ''$http'' en el propio controlador . Ahora vamos a crea un ''provider'' que encapsule la llamada a ''$http''.+Al ver el servicio ''$http'' en el tema [[unidades:03_servicios:02_http]] vimos que no debía hacerse una llamada a ''$http'' en el propio controlador . Ahora vamos a crear un ''provider'' que encapsule la llamada a ''$http''.
  
-El servicio será un objeto llamado ''remoteResource'' que nos permitirá acceder al servidor para acceder a los datos. Como aun no hemos visto la parte de servidor ni la parte de REST solo vamos a hacer un único método sencillo que nos permita leer los datos, mas adelante en el curso seguiremos mejorando este servicio. Por lo tanto aun será un poco chapuza el ejemplo.+El servicio será un objeto llamado ''remoteResource'' que nos permitirá acceder al servidor para acceder a los datos. Como aún no hemos visto la parte de servidor ni la parte de REST ni las promesas , sólo vamos a hacer un único método sencillo que nos permita leer los datos. Más adelante en el curso seguiremos mejorando este servicio. Por lo tanto aun será un poco chapuza el ejemplo.
  
-Nuestro servicio va a ser un ''provider'' ya que tenemos que indicar la +===== La configuración ===== 
 + 
 +Nuestro servicio va a ser un ''provider'' ya que tenemos que indicar la url a partir de la que debemos bajar los datos. Como hemos hecho en el tema anterior éso lo pondremos en una constante de nuestra aplicación. 
 + 
 +<sxh js> 
 +app.constant("baseUrl","."); 
 +</sxh> 
 + 
 +La constante vale el valor "." porque los datos a bajar están en la misma ruta que nuestra página web. 
 + 
 +El provider tendrá un único método para configurarlo llamado ''setBaseUrl'' por lo que tendremos el siguiente bloque config: 
 +<sxh js> 
 +app.config(['baseUrl','remoteResourceProvider',function(baseUrl,remoteResourceProvider){ 
 +  remoteResourceProvider.setBaseUrl(baseUrl); 
 +}]); 
 +</sxh> 
 + 
 +Fíjate cómo el nombre del provider es "remoteResourceProvider", es decir que acaba en "Provider" aunque nuestro servicio sólo se llama "remoteResource". 
 + 
 +===== El provider ===== 
 +Ahora vamos a definir el provider 
 +<sxh js;highlight: [1,3,6,7,11]> 
 +function RemoteResourceProvider() { 
 +  var _baseUrl; 
 +  this.setBaseUrl=function(baseUrl) { 
 +    _baseUrl=baseUrl; 
 +  } 
 +  this.$get=['$http',function($http) { 
 +    return new RemoteResource($http,_baseUrl); 
 +  }]; 
 +} 
 + 
 +app.provider("remoteResource",RemoteResourceProvider); 
 +</sxh> 
 + 
 +  * Línea 1: Definimos el constructor de la clase ''RemoteResourceProvider'' 
 +  * Línea 3: Un método público llamado ''setBaseUrl'' para configurar el servicio. Éste es el método que hemos llamado desde el bloque config. 
 +  * Línea 6: El método ''$get'', que es el factory-provider con la función de factoría a la que se le inyecta el servicio de ''$http''. 
 +  * Línea 7: Ahora la función de factoría crea el nuevo objeto de la clase ''RemoteResource'', siendo esta clase realmente la que hace todo el trabajo y la que se usará desde el controlador. En el constructor además de pasarle el ''$http'' que necesita, también se le pasa la URL Base para configurar el servicio. 
 +  * Línea 11: Finalmente se registra el ''provider''. 
 + 
 +===== La clase del propio servicio ===== 
 +Por último nos queda definir la propia clase que implementa el servicio que hemos llamado ''RemoteResource''. 
 + 
 +Esta clase tiene un único método llamado ''get''. Este método acepta como parámetros dos funciones de callback . La primera función se llamará si se han podido obtener los datos y tiene como parámetro los datos obtenidos. La segunda función se llamará si ha habido algún error y tiene como parámetros los datos obtenidos y el estado HTTP. 
 + 
 +<sxh js;highlight: [1,2,5,7,9]> 
 +function RemoteResource($http,baseUrl) { 
 +  this.get=function(fnOK,fnError) { 
 +        $http({ 
 +          method: 'GET',  
 +          url: baseUrl+'/datos.json' 
 +        }).success(function(data, status, headers, config) { 
 +            fnOK(data); 
 +        }).error(function(data, status, headers, config) { 
 +            fnError(data,status); 
 +        }); 
 +      } 
 +} 
 +</sxh> 
 +  * Línea 1: Al constructor de la clase le pasamos el servicio ''$http'' y la URL Base desde la que pedir los datos. 
 +  * Línea 2: Es el único método público llamado ''get'' y como ya hemos dicho acepta dos funciones como parámetros. 
 +  * Línea 5: La URL que se usará se calcula en función del parámetro ''baseUrl''. 
 +  * Línea 7: Si todo va bien y se han podido obtener los datos, se llama a la función de callback llamada ''fnOK'' pasando como argumento los datos obtenidos. 
 +  * Línea 9: Si algo ha fallado, se llama a la función de callback llamada ''fnError'' pasando como argumentos los datos obtenidos y el estado HTTP. 
 + 
 +===== El controlador ===== 
 +Por último nos queda ver cómo queda el controlador al usar el nuevo servicio. 
 + 
 +<sxh js;highlight: [1,26,27,28,29,30]> 
 +app.controller("SeguroController",['$scope','remoteResource',function($scope,remoteResource) { 
 +  $scope.seguro={ 
 +    nif:"", 
 +    nombre:"", 
 +    ape1:"", 
 +    edad:undefined, 
 +    sexo:"", 
 +    casado:false, 
 +    numHijos:undefined, 
 +    embarazada:false, 
 +    coberturas: { 
 +      oftalmologia:false, 
 +      dental:false, 
 +      fecundacionInVitro:false 
 +    }, 
 +    enfermedades:{ 
 +      corazon:false, 
 +      estomacal:false, 
 +      rinyones:false, 
 +      alergia:false, 
 +      nombreAlergia:"" 
 +    }, 
 +    fechaCreacion:new Date() 
 +  } 
 +   
 +  remoteResource.get(function(seguro) { 
 +    $scope.seguro=seguro; 
 +  },function(data,status) { 
 +    alert("Ha fallado la petición. Estado HTTP:"+status); 
 +  }); 
 +   
 +}]); 
 +</sxh> 
 + 
 +  * Línea 1: Ahora en el controlador en vez de inyectar el servicio ''$http'' se inyecta el servicio ''remoteResource''. 
 +  * Linea 26: Se llama al método ''get'' del servicio ''remoteResource'' y se le pasa como argumentos las 2 funciones. 
 +  * Línea 27: Si todo va bien , se pasan los datos a la propiedad ''seguro'' del ''$scope''. 
 +  * Línea 28: Es la segunda función anónima que se llama si hay algún error. 
 +  * Línea 29: Si falla algo se ejecuta el ''alert''. 
 +===== Ejemplo ===== 
 +El código completo del ejemplo es el siguiente: 
 + 
 +<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> 
 +  </head> 
 +  <body ng-controller="SeguroController"> 
 +    <form> 
 +      <fieldset> 
 +        <legend>Seguro Médico</legend> 
 +          <label for="nif">NIF:</label><input id="nif" name="nif" type="text" ng-model="seguro.nif" /><br> 
 +          <label for="nombre">Nombre:</label><input id="nombre" name="nombre" type="text" ng-model="seguro.nombre" /><br> 
 +          <label for="ape1">1º Apellido:</label><input id="ape1" name="ape1" type="text" ng-model="seguro.ape1" /><br> 
 +          <label for="edad">Edad:</label><input id="edad" name="edad" type="text" ng-model="seguro.edad" /><br> 
 +          <label for="sexo">Sexo:</label><select id="sexo" name="sexo" type="checkbox" ng-model="seguro.sexo" ><option value="">--Elige opcion--</option><option value="H">Hombre</option><option value="M">Mujer</option></select><br> 
 +          <label for="casado">Casado:</label><input id="casado" name="casado" type="checkbox" ng-model="seguro.casado" /><br> 
 +          <label for="numHijos">Nº Hijos:</label><input id="numHijos" name="numHijos" type="text" ng-model="seguro.numHijos" /><br> 
 +          <label for="embarazada">Embarazada:</label><input id="embarazada" name="embarazada" type="checkbox" ng-model="seguro.embarazada" /><br> 
 +          <label for="fechaCreacion">Fecha de creaci&oacute;n:</label><input id="fechaCreacion" name="fechaCreacion" type="text" ng-model="seguro.fechaCreacion" /><br> 
 +      </fieldset> 
 +      <fieldset> 
 +        <legend>Coberturas</legend> 
 +          <label for="oftalmologia">Oftalmologia:</label><input id="oftalmologia" name="oftalmologia" type="checkbox" ng-model="seguro.coberturas.oftalmologia" /><br> 
 +          <label for="dental">Dental:</label><input id="dental" name="dental" type="checkbox" ng-model="seguro.coberturas.dental" /><br> 
 +          <label ng-show="seguro.sexo==='M'" for="fecundacionInVitro">Fecundacion In Vitro:</label><input ng-show="seguro.sexo==='M'" id="fecundacionInVitro" name="fecundacionInVitro" type="checkbox" ng-model="seguro.coberturas.fecundacionInVitro" /><br> 
 +      </fieldset>       
 +      <fieldset> 
 +      <legend>Enfermedades</legend> 
 +          <label for="corazon">Corazon:</label><input id="corazon" name="corazon" type="checkbox" ng-model="seguro.enfermedades.corazon" /><br> 
 +          <label for="estomacal">Estomacal:</label><input id="estomacal" name="estomacal" type="checkbox" ng-model="seguro.enfermedades.estomacal" /><br> 
 +          <label for="rinyones">Ri&ntilde;ones:</label><input id="rinyones" name="rinyones" type="checkbox" ng-model="seguro.enfermedades.rinyones" /><br> 
 +          <label for="alergia">Alergia:</label><input id="alergia" name="alergia" type="checkbox" ng-model="seguro.enfermedades.alergia" /><br> 
 +          <label for="nombreAlergia">Nombre de la alergia:</label><input ng-disabled="seguro.enfermedades.alergia===false" id="nombreAlergia" name="nombreAlergia" type="text" ng-model="seguro.enfermedades.nombreAlergia" /><br> 
 +      </fieldset>  
 +    </form> 
 +  </body> 
 +</html> 
 +</sxh> 
 + 
 +<sxh js;title:script.js> 
 +var app = angular.module("app", []); 
 + 
 +function RemoteResource($http,baseUrl) { 
 +  this.get=function(fnOK,fnError) { 
 +        $http({ 
 +          method: 'GET',  
 +          url: baseUrl+'/datos.json' 
 +        }).success(function(data, status, headers, config) { 
 +            fnOK(data); 
 +        }).error(function(data, status, headers, config) { 
 +            fnError(data,status); 
 +        }); 
 +      } 
 +} 
 + 
 +function RemoteResourceProvider() { 
 +  var _baseUrl; 
 +  this.setBaseUrl=function(baseUrl) { 
 +    _baseUrl=baseUrl; 
 +  } 
 +  this.$get=['$http',function($http) { 
 +    return new RemoteResource($http,_baseUrl); 
 +  }]; 
 +} 
 + 
 +app.provider("remoteResource",RemoteResourceProvider); 
 + 
 + 
 + 
 +app.constant("baseUrl", "."); 
 +app.config(['baseUrl', 'remoteResourceProvider',function(baseUrl, remoteResourceProvider) { 
 +    remoteResourceProvider.setBaseUrl(baseUrl); 
 +}]); 
 + 
 + 
 +app.controller("SeguroController", ['$scope', 'remoteResource',function($scope, remoteResource) { 
 +    $scope.seguro = { 
 +      nif: "", 
 +      nombre: "", 
 +      ape1: "", 
 +      edad: undefined, 
 +      sexo: "", 
 +      casado: false, 
 +      numHijos: undefined, 
 +      embarazada: false, 
 +      coberturas: { 
 +        oftalmologia: false, 
 +        dental: false, 
 +        fecundacionInVitro: false 
 +      }, 
 +      enfermedades: { 
 +        corazon: false, 
 +        estomacal: false, 
 +        rinyones: false, 
 +        alergia: false, 
 +        nombreAlergia: "" 
 +      }, 
 +      fechaCreacion: new Date() 
 +    } 
 + 
 +    remoteResource.get(function(seguro) { 
 +      $scope.seguro = seguro; 
 +    }, function(data, status) { 
 +      alert("Ha fallado la petición. Estado HTTP:" + status); 
 +    }); 
 + 
 +  } 
 +]); 
 +</sxh> 
 + 
 +{{url>http://embed.plnkr.co/pmsJkq}} 
 +===== Malas prácticas ===== 
 +En muchos ejemplos que se ven de AngularJS se tiende a definir un provider en un único bloque en vez de definir diversas funciones separadas como hemos hecho aqui. 
 + 
 +Podemos ver el siguiente trazo de código en el que se ha definido el provider usando varias funciones anónimas anidadas. 
 + 
 +<sxh js> 
 +app.provider("remoteResource", function() { 
 +  var _baseUrl; 
 +  this.setBaseUrl = function(baseUrl) { 
 +    _baseUrl = baseUrl; 
 +  } 
 +  this.$get = ['$http', 
 +    function($http) { 
 +      return new function($http, baseUrl) { 
 +        this.get = function(fnOK, fnError) { 
 +          $http({ 
 +            method: 'GET', 
 +            url: baseUrl + '/datos.json' 
 +          }).success(function(data, status, headers, config) { 
 +            fnOK(data); 
 +          }).error(function(data, status, headers, config) { 
 +            fnError(data, status); 
 +          }); 
 +        } 
 +      }($http, _baseUrl); 
 +    } 
 +  ]; 
 +}); 
 +</sxh> 
 + 
 +Este código - aunque funciona - no es recomendable por lo complejo que resulta de entender. 
 + 
 +===== Referencias ===== 
 +  * [[https://github.com/johnpapa/angularjs-styleguide/blob/master/README.md|AngularJS Style Guide by @john_papa]] 
 +  * [[https://github.com/toddmotto/angularjs-styleguide/blob/master/README.md|AngularJS styleguide by @toddmotto]]
unidades/03_servicios/10_ejemploseguro.1406745142.txt.gz · Última modificación: por admin