Ionic Framework, PouchDB y Cloudant: la combinación perfecta totalmente expuesta Parte 03


Esta es una continuación de la serie sobre desarrollo en móviles que comencé aquí. Les recomiendo comenzar a escribir el código fuente desde la parte 1 ya que no se publica el código para descarga.

Ayer mencioné que iba a publicar un nuevo post para contestar una pregunta que recibí en la semana. Notarán el post sobre tips para rendimiento donde la moraleja resumida es que preocuparse por la velocidad de PouchDB contra Sqlite es detenerse en el arbol en lugar de apreciar todo el bosque.

La primera pregunta que recibí fue sobre como hacer para recuperar una lista de objectos y luego recuperar los detalles de un objeto en particular. Como en cualquier correo, tienen la lista de correos y cuando hacen click en uno en particular, verán el contenido en otra ventana. Este mecanismo es la perfecta introducción al concepto de estados que Ionic soporta mediante la inclusión de UI-Router.

Primero hagamos un poco de orden en el código que dejamos en la parte 2 de esta serie. Para los que recién llegan, no hay un download del código, así que vayan a la Parte 1 para que hagan el código paso a paso con el post.

Como podrán ver, tenemos el código todo regado en el archivo app.js lo cual esta mal. Lo que yo suelo hacer es tener un archivo para los controladores (controller), otro para los servicios (service, factory) y dejamos el app.js lo más limpio posible. Esperen!!, services y factories es algo que no había mencionado hasta ahora. Así que toca un poco de introducción.

Los que venimos del mundo de cliente/servidor y objetos y todo eso recordaremos que solíamos tener un super objeto casi global para ciertas tareas que estaba corriendo todo el tiempo esperando que le pidamos cosas. Si es que necesitábamos mantener la consistencia de sus operaciones, entonces declarábamos este objeto como un Singleton y listo, estabamos seguros que todas las operaciones las podíamos verificar antes de mandarlas. Pues eso en el mundo de AngularJS lo encontramos en las estructuras Service y Factory. ¿Cuál usar? Personalmente yo utilizo Factory la mayor parte del tiempo, pero Service también debería hacer el trabajo. La diferencia principal es que Factory es un Singleton y Service no, nada mas.

Comencemos por el mas fácil, pongamos todos los controladores en un módulo:

angular.module('controllers',[])
.controller('newsController',function($scope){
	$scope.notas=[];
	$scope.$on('refrescar',function(event,news){
		$scope.$apply(function(){
			$scope.notas = news;
		})
	})
})

Llamemos a este archivo controllers.js y pondremos aquí todos los demás controladores que nos hagan falta.

Ahora, para que el cambio sea completo, hay que cambiar tanto el app.js y el index.html.

angular.module('starter', ['ionic','controllers'])

Esta es la única línea que cambia del archivo app.js. Simplemente le estamos diciendo a AngularJS que el módulo App.js llamado ‘starter’, tiene una dependencia adicional llamada ‘controllers’.

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8">
 <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
 <title></title>
 <!-- compiled css output -->
 <link href="css/ionic.app.css" rel="stylesheet">
 <!-- ionic/angularjs js -->
 <script src="lib/ionic/js/ionic.bundle.js"></script>
 <!-- cordova script (this will be a 404 during development) -->
 <script src="cordova.js"></script>
 <!-- your app's js -->
 <script src="js/controllers.js"></script>
 <script src="js/app.js"></script>
 <script src="lib/pouchdb/dist/pouchdb.js"></script>
 </head>

En el caso de index.html, hemos agregado la línea 14 donde le indicamos que tiene que cargar el archivo controllers.js con nuestros controladores. Y listo, ya tenemos algo mas de orden.

Ahora nos toca ordenar la base de datos. Lo ideal sería tener un objeto que esté siempre disponible gestionando las llamadas a la base de datos, por lo que aplica a ser un Service o un Factory. Prefiero un factory como ya les había dicho así que esto quedaría en un módulo de la siguiente manera.

angular.module('services',[])
.factory('db',function($rootScope){
    var key = 'bentareadyessharyinessee';
	var pass = 'OnEixgKgpt8LyEtl0S5DkAon';
	var remote = 'https://'+key+':'+pass+'@supermio.cloudant.com/news';
	var db = new PouchDB('news');

    return {
        init: function(){
            db.replicate.from(remote,{live:true,retry:true})
                .on('paused',function(info){
                db.allDocs({startkey:'news_\uffff',endkey:'news_',descending: true,include_docs:true})
                    .then(function(result){
                    $rootScope.$broadcast('refrescar',result.rows);
                });
            });
        }
    }
})

Llamaremos services.js a este archivo y como podrán ver es un Factory que publica solamente un método llamado init. Este método tenemos que invocar para que se inicie el manejo de la base de datos. Si queremos simplificar nuestro archivo de controladores quedará así:

angular.module('controllers',['services'])
.controller('newsController',function($scope,db){
 db.init();
 $scope.notas=[];
 $scope.$on('refrescar',function(event,news){
 $scope.$apply(function(){
 $scope.notas = news;
 })
 })
})

Notarán que en la línea 1 se ha agregado el módulo services como dependencia y en la línea 3 estamos llamando al método init del Factory db.

Y el app.js quedará así:

angular.module('starter', ['ionic','controllers'])

.run(function($ionicPlatform,$rootScope) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if(window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if(window.StatusBar) {
      StatusBar.styleDefault();
    }
  });
})

Comparado con el desorden que teníamos al principio ahora todo se ve más ordenado. Pero lo mas importante es que podemos centrarnos en escribir servicios o factories de forma general y reutilizarlos en otros proyectos simplemente copiando los archivos, lo mismo con controladores.

Una sugerencia final es que según estuve leyendo, esto de separar el código en controladores y servicios es bueno, pero no sirve si nuestro proyecto crece demasiado. La solución es la de hacer la separación por funciones de nuestro app y dentro de cada función poner los controladores y servicios separados en archivos. Esto lo veremos mejor cuando incluyamos el concepto de estados.

Continuaremos en otro Post porque el tema de estados es muy importante entender el concepto antes de programar.

NOTA: Soy muy flojo programando, así que hacer todo esto paso a paso lo hago para combatir este defecto. Así que para notar que este esfuerzo vale la pena, les pido que sigan el tutorial desde la parte 1, si les paso el código para que lo copien simplemente no vale ni mi esfuerzo ni ustedes tampoco van a entender.


  1. Reblogged this on Dinesh Ram Kali..

  1. 1 Ionic Framework, PouchDB y Cloudant: la combinación perfecta totalmente expuesta | Víctor Pease

    […] Part 3 […]




Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s



%d bloggers like this: