Diferencias

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

Enlace a la vista de comparación

unidades:07_rutas:04_resolve [2014/08/26 22:12]
admin [La ruta con el resolve]
unidades:07_rutas:04_resolve [2014/09/16 19:25] (actual)
admin
Línea 1: Línea 1:
 ====== 7.4 Resolve ====== ====== 7.4 Resolve ======
-Ya hablamos en [[unidades:​06_promesas:​01_justificacion#​resueltos_antes_de_llamar_al_controlador|Resueltos antes de llamar al controlador]] ​sobre la importancia que tenían las promesas en el servicio de rutas. Ahora vamos a explicar esa importancia y volveremos a usar las [[unidades:​06_promesas:​03_avanzado#​objeto_con_promesas|promesas en paralelo con un objeto]].+Ya hablamos en [[unidades:​06_promesas:​01_justificacion#​resueltos_antes_de_llamar_al_controlador|Resueltos antes de llamar al controlador]] ​de la importancia que tenían las promesas en el servicio de rutas. Ahora vamos a explicar esa importancia y volveremos a usar las [[unidades:​06_promesas:​03_avanzado#​objeto_con_promesas|promesas en paralelo con un objeto]].
  
 Lo que vamos a ver es una funcionalidad del método ''​when''​ de [[unidades:​07_rutas:​02_routeprovider|$routeProvider]]. ​ Lo que vamos a ver es una funcionalidad del método ''​when''​ de [[unidades:​07_rutas:​02_routeprovider|$routeProvider]]. ​
  
-Al definir una ruta , en el método ''​when'',​ le pasamos un objeto con las propiedades ''​templateUrl''​ y ''​controller''​. Este objeto puede tener más propiedades que no vamos a ver excepto la propiedad ''​resolve''​. Esta propiedad la podemos ver como el objeto que vimos en [[unidades:​06_promesas:​03_avanzado#​objeto_con_promesas|promesas en paralelo con un objeto]].+Al definir una ruta , en el método ''​when'',​ le pasamos un objeto con las propiedades ''​templateUrl''​ y ''​controller''​. Este objeto puede tener más propiedades que no vamos a ver excepto la propiedad ''​resolve''​. Esta propiedad la podemos ver similar al objeto que vimos en [[unidades:​06_promesas:​03_avanzado#​objeto_con_promesas|promesas en paralelo con un objeto]].
  
-El objeto ''​resolve''​ contiene en cada una de sus propiedades funciones que retornan promesas ​ ((No hace falta que retorne obligatoriamente promesas , también puede retornar valores directamente)) que se resolverán antes de llamar al controlador y que se pueden acceder desde el controlador si se inyectan en él.+El objeto ''​resolve''​ contiene en cada una de sus propiedades funciones que retornan promesas ​ ((No hace falta que retorne obligatoriamente promesas , también puede retornar valores directamente)) que se resolverán antes de llamar al controlador y a las que se pueden acceder desde el controlador si se inyectan en él.
  
-¿Cual ​es la utilidad de ésto? Para mi son dos: +¿Cuál ​es la utilidad de ésto? Para mí son dos: 
-  * En las directivas. Las directivas a veces necesitan información nada inicializarse, ​ antes de que se compilen ((Ya veremos ​mas adelante ​que es compilar una directiva)). Si esa información se obtiene del ''​$scope''​ del controlador y no aun no está disponible porque el controlador ha hecho una llamada asíncrona ((Ej. llamar a ''​$http''​)),​ no se tienen los datos a tiempo para la directiva. +  * En las directivas. Las directivas a veces necesitan información nada más inicializarse,​ antes de que se compilen ((Ya veremos ​más adelante ​qué es compilar una directiva)). Si esa información se obtiene del ''​$scope''​ del controlador y aún no está disponible porque el controlador ha hecho una llamada asíncrona ((Ej. llamar a ''​$http''​)),​ no se tienen los datos a tiempo para la directiva. 
-  * En la página HTML: Si la página muestra datos que se cargan en el controlador mediante ''​$http''​ ((o similar), podemos ver la página ya cargada pero los campos ​aun en blanco ya que aun estamos ​esperando los datos de la llamada a ''​$http''​. ​Esto queda un poco mal para el usuario ya que ve una página sin datos y un instante después aparecen //por arte de mágia// los datos.+  * En la página HTML: Si la página muestra datos que se cargan en el controlador mediante ''​$http''​ ((o similar)), podemos ver la página ya cargada pero los campos ​aún están ​en blanco ya que seguimos ​esperando los datos de la llamada a ''​$http''​. ​Ésto queda un poco mal para el usuario ya que ve una página sin datos y un instante después aparecen //por arte de mágia// los datos.
  
-La solución a estos 2 problemas sería hacer las llamadas asíncronas antes de mostrar la página y no mostrar la página hasta que no se hayan obtenido los datos. Pues bien , eso es justo lo que hace ''​resolve''​. No navegará hasta la ruta hasta que no estén todos los datos que necesitamos ​disponibles.+La solución a estos 2 problemas sería hacer las llamadas asíncronas antes de mostrar la página y no mostrar la página hasta que no se hayan obtenido los datos. Pues bien, éso es justo lo que hace ''​resolve''​. No navegará hasta la ruta hasta que no estén ​disponibles ​todos los datos que necesitamos.
  
-Veamos ahora un ejemplo de como se usa. como es un poco complejo vamos a ir haciéndolo paso a paso.+Veamos ahora un ejemplo de cómo se usa. Como es un poco complejovamos a ir haciéndolo paso a paso.
  
 ===== El servicio sumaAsincrona ===== ===== El servicio sumaAsincrona =====
Línea 41: Línea 41:
 </​sxh>​ </​sxh>​
  
-Creamos el servicio ''​sumaAsincrona''​ que es una función que acepta 2 parámetros. No se deberían ​tener problemas ​en entender este código ya que en unidades ​anterior ​vimos como crear servicios. En caso de dudas puedes repasar el tema [[unidades:​03_servicios:​08_factory|3.8 factory]]+Creamos el servicio ''​sumaAsincrona''​ que es una función que acepta 2 parámetros. No deberíamos ​tener problemas ​para entender este código ya que en unidades ​anteriores ​vimos cómo crear servicios. En caso de dudaspuedes repasar el tema [[unidades:​03_servicios:​08_factory|3.8 factory]]
  
 ===== La ruta con el resolve ===== ===== La ruta con el resolve =====
-Ahora vamos a crear una ruta para que haga uso del servicio ''​sumaAsincrona''​ el cual retorna una promesa.+Ahora vamos a crear una ruta para que haga uso del servicio ''​sumaAsincrona''​el cual retorna una promesa.
  
 <sxh js;​highlight:​ [4,​5,​6,​7,​8]>​ <sxh js;​highlight:​ [4,​5,​6,​7,​8]>​
Línea 60: Línea 60:
   * Línea 5: La propiedad del objeto ''​resolve''​ se llama ''​suma2y3''​ y es una función a la que se le inyecta el servicio de ''​sumaAsincrona''​. Posteriormente en el controlador podremos inyectar un servicio llamado ''​suma2y3''​ que contendrá el resultado de la promesa.   * Línea 5: La propiedad del objeto ''​resolve''​ se llama ''​suma2y3''​ y es una función a la que se le inyecta el servicio de ''​sumaAsincrona''​. Posteriormente en el controlador podremos inyectar un servicio llamado ''​suma2y3''​ que contendrá el resultado de la promesa.
   * Línea 6: Retornamos la promesa que ha creado ''​sumaAsincrona''​.   * Línea 6: Retornamos la promesa que ha creado ''​sumaAsincrona''​.
 +  * Línea 7: Cerramos el array y la función.
 +  * Línea 8: Cerramos el objeto ''​resolve''​.
  
 Al definir así la ruta , no se navegará hasta la página hasta que no se haya resuelto la promesa.De esa forma al llamar al controlador ya tendremos el dato calculado. Al definir así la ruta , no se navegará hasta la página hasta que no se haya resuelto la promesa.De esa forma al llamar al controlador ya tendremos el dato calculado.
 +
 +<note tip>
 +Al principio queda un poco raro que sea un objeto ''​resolve''​ que tiene propiedades cuyos valores son funciones y que esas funciones retornan promesas.
 +</​note>​
  
 ===== El uso desde el controlador ===== ===== El uso desde el controlador =====
 +Ahora en el controlador ya podemos inyectar un nuevo //​servicio//​ llamado ''​suma2y3''​ cuyo valor será el resultado de la promesa.
 +
 +<sxh js;​highlight:​ [1,2]>
 +app.controller("​Pagina1Controller",​ ["​$scope","​suma2y3",​function($scope,​suma2y3) {
 +   ​$scope.mensaje2y3="​suma de 2 y 3 es " + suma2y3;
 +}]);
 +</​sxh>​
 +  * Línea 1: Inyectamos el servicio ''​suma2y3''​ el cual existe gracias al ''​resolve''​ de la ruta.
 +  * Línea 2: Hacemos uso del valor directamente sin tener que esperarnos.
 +
 +
 +<note important>​
 +No vamos a ver el caso de que la promesa sea rechazada, ya que se complica un poco cómo tratarlo.
 +Aunque tienes el siguiente blog donde lo explican: [[http://​www.thinkster.io/​angularjs/​o1YnQ52SOd/​angularjs-resolve-routechangeerror|AngularJS - resolve $routeChangeError]]
 +</​note>​
 +===== Parámetros =====
 +Lo siguiente que vamos a ver es qué ocurre si necesitamos que la promesa use los datos de la ruta para hacer los cálculos. Podríamos pensar que es tan sencillo como usar ''​$routeParams''​ pero en el ''​resolve''​ no es posible usar ''​$routeParams''​ sino que tenemos que usar ''​$route.current.params''​.
 +
 +Veamos ahora un ejemplo en el que suponemos que los datos a sumar vienen como parámetros de la ruta.
 +
 +<sxh js;​highlight:​ [1,​5,​6,​7,​8]>​
 +  $routeProvider.when('/​pagina1/:​a/:​b',​ {
 +    templateUrl:​ "​pagina1.html",​
 +    controller: "​Pagina1Controller",​
 +    resolve: {
 +      suma2y3:​['​sumaAsincrona','​$route',​function(sumaAsincrona,​$route) {
 +        var a=parseInt($route.current.params.a);​
 +        var b=parseInt($route.current.params.b);​
 +        return sumaAsincrona(a,​b);​
 +      }]]
 +    }
 +  });
 +</​sxh>​
 +
 +  * Línea 1: La ruta ahora incluye los parámetros ''​a''​ y ''​b''​.
 +  * Línea 5: Inyectamos el servicio ''​$route''​ para tener acceso al valor de los parámetros.
 +  * Línea 6 y 7 : Accedemos a los parámetros mediante ''​$route.current.params.a''​ y ''​$route.current.params.b''​ y los transformamos en un integer ya que son Strings
 +  * Línea 8: Hacemos la suma con los valores de los parámetros
 +
 +
 ===== Ejemplo ===== ===== Ejemplo =====
 +En este ejemplo lo que hacemos es mostrar 2 páginas llamadas:
 +  * ''​pagina1.html'':​ Hacemos 2 sumas asíncronas pero calculamos su valor en el ''​resolve''​. Ésto hace que se tarde 3 segundos desde que se pincha hasta que se muestra la página.
 +  * ''​pagina2.html''​ : También hacemos 2 sumas asíncronas pero calculamos su valor en el controlador. Ésto hace que la página se muestre inmediatamente tras pinchar pero los datos no se ven hasta pasados 3 segundos.
  
-{{url>​http://​embed.plnkr.co/bCQP74}}+En ambos casos los valores para hacer las 2 sumas (4 números en total) se obtienen de la rutaDe esa forma se ve la diferencia al obtener los parámetros en el controlador ((mediante ''​$routeParams''​)) o en el ''​resolve''​ ((mediante ''​$route.current.params''​)).
  
 +También en ambos casos se hacen 2 sumas para ver cómo se puede usar más de una propiedad en el ''​resolve''​.
 +
 +<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='//​ajax.googleapis.com/​ajax/​libs/​angularjs/​1.2.19/​angular-route.min.js'></​script>​
 +  <script src="//​code.angularjs.org/​1.2.19/​i18n/​angular-locale_es-es.js"></​script>​
 +  <script src="​script.js"></​script>​
 +</​head>​
 +
 +<​body>​
 +  <​h1>​Esto es el titulo y no cambia</​h1>​
 +  <ul>
 +    <​li><​a href="#/​pagina1/​2/​3/​7/​9">​Ir a la p&​aacute;​gina 1.</​a>​.Aqui se tardar&​aacute;​ en mostrar la p&​aacute;​gina pero ya estar&​aacute;​n los datos calculados.</​li>​
 +    <​li><​a href="#/​pagina2/​2/​3/​7/​9">​Ir a la p&​aacute;​gina 2</​a>​.La p&​aacute;​gina se cargar&​aacute;​ inmediatamente pero se tardar&​aacute;​ en calcular los datos</​li>​
 +  </ul>
 +  <div ng-view></​div>​
 +
 +  <​h3>​Esto es un pie y no cambia</​h3>​
 +
 +</​body>​
 +
 +</​html>​
 +</​sxh>​
 +
 +<sxh js;​title:​script.js>​
 +
 +var app = angular.module("​app",​ ['​ngRoute'​]);​
 +
 +app.factory("​sumaAsincrona",​['​$q','​$timeout',​function($q,​$timeout) {
 +  ​
 +  return function (a,b) {
 +     var defered=$q.defer();​
 +     var promise=defered.promise;​
 +      ​
 +     ​$timeout(function() {
 +        try{
 +           var resultado=a+b;​
 +           ​defered.resolve(resultado);​
 +        } catch (e) {
 +           ​defered.reject(e);​
 +        }   
 +     ​},​3000); ​
 +      ​
 +     ​return promise;
 +  } 
 +  ​
 +}]);
 +
 +
 +app.config(['​$routeProvider',​function($routeProvider) {
 +
 +  $routeProvider.when('/​pagina1/:​a/:​b/:​c/:​d',​ {
 +    templateUrl:​ "​pagina1.html",​
 +    controller: "​Pagina1Controller",​
 +    resolve: {
 +      suma2y3:​['​sumaAsincrona','​$route',​function(sumaAsincrona,​$route) {
 +        var a=parseInt($route.current.params.a);​
 +        var b=parseInt($route.current.params.b);​
 +        return sumaAsincrona(a,​b);​
 +      }],
 +      suma7y9:​['​sumaAsincrona','​$route',​function(sumaAsincrona,​$route) {
 +        var c=parseInt($route.current.params.c);​
 +        var d=parseInt($route.current.params.d);​
 +        return sumaAsincrona(c,​d);​
 +      }]
 +    }
 +  });
 +    ​
 +  $routeProvider.when('/​pagina2/:​a/:​b/:​c/:​d',​ {
 +    templateUrl:​ "​pagina2.html",​
 +    controller: "​Pagina2Controller"​
 +  });
 +    ​
 +  ​
 +  ​
 +  ​
 +  $routeProvider.otherwise({
 +        redirectTo: '/​pagina1/​nada'​
 +  });   
 +
 +}]);
 +
 +
 +app.controller("​Pagina1Controller",​ ["​$scope","​suma2y3","​suma7y9",​function($scope,​suma2y3,​suma7y9) {
 +   ​$scope.mensaje2y3="​suma de 2 y 3 es " + suma2y3;
 +   ​$scope.mensaje7y9="​suma de 7 y 9 es " + suma7y9;
 +}]);
 +
 +
 +
 +
 +app.controller("​Pagina2Controller",​ ["​$scope","​$routeParams","​sumaAsincrona",​function($scope,​$routeParams,​sumaAsincrona) {
 +  var a=parseInt($routeParams.a);​
 +  var b=parseInt($routeParams.b);​
 +  var c=parseInt($routeParams.c);​
 +  var d=parseInt($routeParams.d);​
 +        ​
 +  sumaAsincrona(a,​b).then(function(resultado){
 +        $scope.mensaje2y3="​suma de 2 y 3 es " + resultado;
 +  });
 +  ​
 +  sumaAsincrona(c,​d).then(function(resultado){
 +     ​$scope.mensaje7y9="​suma de 7 y 9 es " + resultado;
 +  });
 +  ​
 +}]);
 +</​sxh>​
 +
 +
 +<sxh html;​title:​pagina1.html>​
 +<​h1>​Soy la pagina 1</​h1> ​
 +Al mostrar la página ya se ven los datos:
 +<br>
 +{{mensaje2y3}}
 +<br>
 +{{mensaje7y9}}
 +</​sxh>​
 +
 +<sxh html;​title:​pagina2.html>​
 +<​h1>​Soy la pagina 2</​h1>​
 +Estamos esperando a que se muestren los datos
 +<br>
 +.....
 +<br>
 +......
 +<br>
 +{{mensaje2y3}}
 +<br>
 +{{mensaje7y9}}
 +
 +</​sxh>​
 +
 +
 +
 +{{url>​http://​embed.plnkr.co/​bCQP74}}
  
 ===== Referencias ===== ===== Referencias =====
   * [[https://​docs.angularjs.org/​api/​ngRoute/​provider/​$routeProvider|$routeProvider]]   * [[https://​docs.angularjs.org/​api/​ngRoute/​provider/​$routeProvider|$routeProvider]]
   * [[https://​docs.angularjs.org/​api/​ng/​service/​$q|$q]]   * [[https://​docs.angularjs.org/​api/​ng/​service/​$q|$q]]
 +  * [[http://​www.thinkster.io/​angularjs/​o1YnQ52SOd/​angularjs-resolve-routechangeerror|AngularJS - resolve $routeChangeError]]
unidades/07_rutas/04_resolve.1409083932.txt.gz · Última modificación: 2014/08/26 22:12 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