Tutorial de AngularJS #2

En este segundo capítulo del Tutorial de AngularJS nos enfocaremos en definir nuestro proyecto, el flujo y la interfaz. También aprenderemos a crear un controlador y a usar JSON.

Como bien leyeron en el capitulo anterior, AngularJS es un framework que es capaz de convertir una página estática hecha en HTML en una aplicación web, así de simple.

El concepto “single-page app” es cada vez más común en Internet así como los frameworks de desarrollo que permiten la creación de éstas. Aplicaciones de música como Soundcloud, Rdio o el famoso Spotify, por nombrar solo algunos, son claros ejemplos de single-page apps.

Por eso es que para nuestro tutorial haremos un proyecto — de pequeña escala, nada muy avanzado — de una “single-page app”. El proyecto se llamará GIF Wallet y tendrá por objetivo hacer una aplicación para guardar Gifs y luego reutilizarlos. Convengamos que no es un proyecto tan interesante ni tampoco representa un gran desafío; pero les aseguro que nos será suficiente para aprender.

El proyecto

Antes de comenzar a desarrollar debemos tener claro cómo va a funcionar la aplicación, es por eso que hice un diagrama que nos permitirá visualizar a grandes rasgos como va a ser nuestra aplicación.

Vista Principal
Se mostrarán los gifs que tengamos en nuestra wallet. Se podrán favoritear, eliminar y previsualizar haciendo click en la foto
Vista de Búsqueda
Esta vista permitirá buscar a través de la API de Giphy nuevas imágenes que nos gustaría almacenar en nuestra Wallet
Previsualización
Al presionar un GIF se mostrará un diálogo con más detalles y más grande
Añadir usando LINK
Para agregar imágenes directamente con un LINK, se mostrará otro diálogo que permita agregarlo a la lista

Teniendo estos puntos claros podemos definir otros detalles como por ejemplo:

  • Estructura de directorios: Utilizaremos la misma que planteamos en el tutorial anterior.
  • Interfaz: Para agilizar el diseño usaremos Bootstrap. Para quienes no conocen Bootstrap pueden visitar su sitio web.

Manos al código

Para la estructura de directorios usaremos el ejemplo del capítulo anterior, usar una estructura predefinida es clave si queremos estar ordenados en nuestro desarrollo.

Para nuestra Vista Principal usaremos el archivo index.html, los estilos estarán en el archivo app.css y la aplicación la programaremos en el archivo app.js.

La vista principal

Comenzaremos por las cabeceras del archivo, agregando “AngularJS” y “Bootstrap” del siguiente modo:

<!doctype html>
<html lang="es">

<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="app.css">

    <script src="javascripts/angularjs.js"></script>
    <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
    <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>

    <script src="src/app.js"></script>
    <title>GIF Wallet</title>
</head>

Ahora crearemos la interfaz completa, tal cual como aparece en el diagrama, de la siguiente forma:

<body>
    <div class="container">
        <header>
            <ul class="nav nav-pills pull-right">
                <li class="active">
                    <a href="#">
                        <span class="glyphicon glyphicon-home"></span>  
                      <span class="badge pull-right">42</span> 
                    </a>
                </li>
                <li>
                    <a href=""><span class="glyphicon glyphicon-plus"></span></a>
                </li>
                <li>
                    <a href=""><span class="glyphicon glyphicon-search"></span></a>
                </li>
            </ul>
            <h3 class="text-muted">GIF Wallet</h3>
        </header>

Creamos el contenedor (.container), luego un header con una barra de navegación y el título, con la clase text-muted. Después, debemos agregar la lista de imágenes del siguiente modo:

<div id="images" class="row">
    <div class="col-lg-12 media">
        <a href="" class="pull-left thumbnail">
            <img class="media-object" src="http://placehold.it/180x180">
        </a>
        <div class="media-object">
            <h4 class="media-heading">Imagen</h4>
            <p>
                <a><span class="glyphicon glyphicon-minus"></span> Eliminar</a>
            </p>    
            <p>
                <a><span class="glyphicon glyphicon-heart"></span> Favorito</a>
            </p>
            <p>
                Link: <a href="">http://link.a.la.imagen</a>
            </p>
        </div>
    </div>
</div>

Aquí, utilizamos la interfaz que nos entrega como ejemplo Bootstrap para los objetos tipo “media“. Y como imagen de ejemplo utilizamos el servicio de “placehold.it“. Después de esto, agregaremos el footer:

        <footer>
            <p>&copy; GIFWallet 2014</p>
        </footer>
    </div>
</body>

</html>

Y para finalizar, agregaremos algunos estilos propios para nuestra interfaz:

body {
    padding: 20px;
}

.container {
    max-width: 800px;
}

.container header {
    overflow: hidden;
    border-bottom: 1px solid #E5E5E5;
}

#images {
    padding: 20px 0;
}

footer {
    border-top: 1px solid #E5E5E5;
    overflow: hidden;
    padding: 20px 0;
}

Con esto ya tenemos suficiente como para ver una aplicación así:

¡A programar!

Lo que se viene ahora es la creación y desarrollo de la aplicación, para esto inicializaremos nuestra aplicación con la directivang-app“.

<html lang="es" ng-app="gifwalletApp">
La directiva “ng-app” se utiliza para auto iniciar la aplicación, generalmente se utiliza en un tag raíz, es decir, que contenga los elementos que vamos a manejar. Para lograr esto vamos a modificar el tag `html` y agregaremos la directiva más el nombre de la aplicación.

Lo que sigue es definir que la aplicación “gifwalletApp” es un módulo dentro de AngularJS, para esto agregaremos al archivo app.js el siguiente código:

var gifwalletApp = angular.module('gifwalletApp', []);

Usando la función angular.module estamos definiendo nuestra aplicación como tal, y aquí hacemos una pausa para responder esa pregunta que de seguro ya se está preguntando.

¿Qué es un módulo?

Respuesta: Un módulo en AngularJS es un contenedor de funcionalidades. Podemos crear cuántos módulos necesitemos y reutilizarlos a medida que programamos. Las funcionalidades que podemos programar y utilizar en un módulo son:

  • Controladores
  • Filtros
  • Servicios
  • Otros

¿Y todo eso está contenido en un módulo?

Respuesta: Sí. Todo eso y más. De hecho, se pueden usar módulos dentro de módulos. ¿Se dieron cuenta que la definición de nuestro módulo tenía al final dos corchetes? Ahí es donde se agregan los módulos que vamos a reutilizar; pero eso es harina de otro costal por ahora pues tenemos que enfocarnos en lo principal: Crear nuestro primer controlador.

Nuestro primer controlador

Un controlador no es alguien que te mande o diga lo que tengas que hacer, es una pieza de código que permite definir la lógica de negocio de tu aplicación. En lenguaje humano, un controlador está programado para controlar como funcionan las cosas, es como la garra.

Para crear un controlador utilizaremos la función “controller“, agregándosela a la variable gifwalletApp que está en el archivo app.js:

gifwalletApp.controller('GifListController', function($scope){

});

Si se dan cuenta, la función controller necesita el nombre del controlador, en este caso será “GifListController” ya que acá es donde programaremos las magias para que se muestre la lista de Gifs.

Y por otra parte, en la definición de la función se encuentra la variable “$scope“, que funciona como conexión entre el controlador, la vista y el modelo. La variable $scope es muy importante porque nos permitirá inyectar datos a nuestro index.html, entre otras cosas más que veremos más adelante.

El siguiente paso es conectar nuestro controlador con la vista, es decir, con el archivo index.html:

<div id="images" class="row" 

Ahora tenemos todo listo y conectado, podremos empezar a programar en nuestro controlador y todo lo que pase tendrá resultados visuales en este espacio.

Integrando JSON

Ahora que tenemos nuestro controlador vamos a agregar otra tecnología que nos hará la vida más simple si la sabemos ocupar, me refiero a JSON.

JSON, acrónimo de JavaScript Object Notation, es un formato ligero para el intercambio de datos. JSON es un subconjunto de la notación literal de objetos de JavaScript que no requiere el uso de XML.

Eso nos dice Wikipedia, pero ¿qué es JSON en palabras simples? Es una forma simple para escribir información compleja, así no más. Por ejemplo, si quisieramos hacer una lista de imágenes (GIF) en formato JSON deberíamos hacerlo del siguiente modo:

   [{
        name: 'Corgi Bailarín',
        url: 'http://media.giphy.com/media/12co3H23YQXLYk/giphy.gif',
        tags: ['corgi', 'baile', 'lol'],
        favorite: true
    }, {
        name: 'Michael Scott',
        url: 'http://media.giphy.com/media/zIPKUgO2Ln6XC/giphy.gif',
        tags: ['the office', 'michael scott', 'asap'],
        favorite: false
    }];

En este caso, la estructura está dada intrinsecamente en nuestro objeto JSON y no es necesario tener un diccionario que nos traduza cada dato que vamos viendo. En el ejemplo vemos un atributo “name“, “url” que es simplemente texto; el atributo “tags” representa una lista o arreglo y el atributo “favorite” es un tipo de dato lógico o booleano.

¿Se entendio? Pues si es así vamos a tener que usar este mismo objeto JSON en nuestro controlador, definiéndolo en una variable:

var images = [{
        name: 'Corgi Bailarín',
        url: 'http://media.giphy.com/media/12co3H23YQXLYk/giphy.gif',
        tags: ['corgi', 'baile', 'lol'],
        favorite: true
    }, {
        name: 'Michael Scott',
        url: 'http://media.giphy.com/media/zIPKUgO2Ln6XC/giphy.gif',
        tags: ['the office', 'michael scott', 'asap'],
        favorite: false
    }];

Y luego, se la pasaremos a la vista usando nuestra variable especial “$scope“:

$scope.giflist = images;

Repetidores

La forma que tiene AngularJS para mostrar resultados que vengan desde una colección de datos — entiéndase colección como un grupo de datos relacionados — es usando repetidores. Se asume que en una colección los datos son similars y guardan relación, es por eso que debemos aplicar una repetición de reglas para cada elemento.

Para hacer uso de la funcionalidad de repetidores usaremos la directiva ng-repeat, que nos permite recorrer por ejemplo, objetos JSON.

La directiva se utiliza dentro de la vista e interviene un elemento que será el que se va a repetir. En nuestro caso usaremos el primer div que está después del controlador:

<div class="col-lg-12 media" ng-repeat="gif in giflist">

Si se dan cuenta, este div contiene toda la información de ejemplo que tenemos prediseñada, por eso es que lo usaremos como repetidor. La directiva ng-repeat va a recorrer la variable “giflist” que definimos en nuestro controlador, y a cada vuelta del ciclo nos entregará la información de un elemento en la variable gif.

¿Qué hacemos con para mostrar la información dentro del repetidor?

Respuesta: Usaremos los brackets dobles para imprimir la variable. Sí, como en un template, miren:

<a href="" class="pull-left thumbnail">
    <img class="media-object" src="{{ gif.url }}">
</a>
<div class="media-object">
    <h4 class="media-heading">{{ gif.name }}</h4>
    <p>
        <a><span class="glyphicon glyphicon-minus"></span> Eliminar</a>
    </p>    
    <p>
        <a><span class="glyphicon glyphicon-heart"></span> Favorito</a>
    </p>
    <p>
        Link: <a href="">{{ gif.url }}</a>
    </p>
</div>

Si miran bien, usamos {{ }} para imprimir información que viene en la variable gif, definida en la directiva ng-repeat. Luego, cada atributo de esa variable se debe acceder usando un punto “.” seguido del nombre del atributo.

Resultado

Así, con todo esto explicado, el código y la aplicación queda del siguiente modo:

Espero que se haya entendido bien este segundo capítulo y si tiene comentarios, no duden en hacerlos acá abajito!

 

Tutorial de AngularJS #3

Blog, Tutorial, Tutorial Javascript
9 minutos