AngularJS: primeros pasos.

10
90263

AngularJS: primeros pasos.

0. Índice de contenidos.


1. Introducción

En plena «era HTML5» y Web 2.0 pocos son los que discuten que Javascript y CSS3 son los reyes absolutos en lo que respecta al desarrollo «front-end». Los sitios web son mucho más dinámicos (algunas web´s ya parecen incluso verdaderas aplicaciones de escritorio) de forma que la experiencia del usuario mejora notablemente.

HTML es un lenguaje para definir documentos estáticos y el camino para dinamizarlos pasa irremediablemente por Javascript. Sin embargo, este proceso de dinamización de documentos HTML puede ser una tarea bastante tediosa que, a menudo, se suele hacer bastante difícil de mantener si no se diseña correctamente.

En este tutorial intentaremos explicar qué es AngularJS y cómo intenta dinamizar los documentos HTML mediante la vinculación (data binding) del modelo de datos con componentes de la vista mediante un ejemplo.


2. Entorno.

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 15′ (2.2 Ghz Intel Core I7, 8GB DDR3).
  • Sistema Operativo: Mac OS Mountain Lion 10.8
  • Entorno de desarrollo: Intellij Idea 11.1 Ultimate.
  • AngularJS 1.0.4

3. Características de AngularJS.

AngularJS es un framework Javascript que corre en el lado del cliente (navegador) y que se centra en intentar dinamizar documentos HTML, lo que comunmente se conoce como DHTML (Dynamic HTML). Normalmente esto se consigue haciendo uso de CSS y Javascript de forma que, en función de los eventos que se produzcan en nuestra página (acciones del usuario, respuestas del servidor vía AJAX o Websockets), se actualizan, crean o eliminan determinados componentes de nuestro DOM (una imagen, un párrafo, o lo que sea…).

El objeto «document» de Javascript nos proporciona una serie de métodos como «getElementById» o «createElement» que nos permiten manipular, crear o eliminar elementos de nuestro documento HTML. No obstante, esto suele ser una tarea relativamente tediosa y muchas veces compleja, sobre todo para la gente que no está acostumbrada a trabajar con Javascript (es cierto que JQuery facilita mucho el trabajo).

AngularJS cambia un poco el enfoque de «dinamización» de documentos HTML estáticos mediante la vinculación de elementos de nuestro documento HTML con nuestro modelo de datos (data binding). De este modo, definimos un modelo de datos (Javascript) que se corresponderá con determinadas partes de nuestro HTML y, siempre que haya cambios en una parte, automáticamente se verán reflejados en la otra.

Veamos un ejemplo para intentar asimilar mejor estos conceptos.

4. Ejemplo: creando un cuestionario con AngularJS.

En este ejemplo vamos a crear un cuestionario con preguntas que deben ser respondidas por el usuario. Para ello partiremos de un set de preguntas que deben ser cargadas en el documento HTML. Además, según vaya respondiendo el usuario a cada pregunta, ésta se deberá actualizar de forma que sepa si ha respondido correctamente o no. Por último tendremos un indicador que muestre el rango del usuario en función de la cantidad de preguntas que va acertando.

Por tanto, nuestros requisitos son:

  • Queremos que las preguntas se carguen dinámicamente en el documento.
  • Por cada pregunta que responda el usuario se debe indicar si la respuesta es correcta o no.
  • Se debe actualizar el rango del usuario en función de las preguntas que vaya acertando.

4.1 Definiendo las preguntas.

En nuestro modelo de datos una pregunta se representaría de la siguiente forma:

{
	id : 1,
	text : 'Esto es una pregunta',
	validAnswer : 1,
	userAnswer : null,
	status : '',
	answers: [
		{id : 1, text : 'Respuesta 1'},
		{id : 2, text : 'Respuesta 2'},
		{id : 3, text : 'Respuesta 3'}
	]
}

Las propiedades de nuestra pregunta son:

  • id: identificador de la pregunta
  • text: enunciado de la pregunta
  • validAnswer: identificador de la respuesta correcta
  • userAnswer: identificador de la respuesta seleccionada por el usuario (null si no ha respondido)
  • status: indica si la pregunta se ha respondido de forma correcta o no
  • answers: listado de posibles respuestas a la pregunta. Cada pregunta está compuesta por un id y un texto

4.2 Definiendo nuestro modelo de datos.

Como explicamos anteriormente, AngularJS vincula nuestro modelo de datos con el documento HTML. Para conseguir esto, hace uso de un objeto scope donde se definen las propiedades del modelo.

function TestController($scope) {
    $scope.questions = [
        {
            id : 1,
            text:'Esto es una pregunta',
            validAnswer : 1,
            userAnswer : null,
            status : '',
            answers: [
                {id : 1, text : 'Respuesta 1.1'},
                {id : 2, text : 'Respuesta 1.2'},
                {id : 3, text : 'Respuesta 1.3'}
            ]
        },
        {
            id : 2,
            text:'Otra pregunta',
            validAnswer : 2,
            userAnswer : null,
            status : '',
            answers: [
                {id : 1, text : 'Respuesta 2.1'},
                {id : 2, text : 'Respuesta 2.2'}
            ]
        }
    ];

    $scope.userStatus = '';

    $scope.validAnswers = 0;

    $scope.validate = function (question) {
        if (question.validAnswer == question.userAnswer) {
            $scope.validAnswers ++;
            question.status = 'ok';
        } else {
            if (question.status == 'ok' && $scope.validAnswers > 0) {
                $scope.validAnswers --;
            }
            question.status = 'error';
        }

        updateUserStatus();
    };

    function updateUserStatus() {
        var avgValidAnswers = ($scope.validAnswers / $scope.questions.length) * 100;
        if (avgValidAnswers == 0) {
            $scope.userStatus = 'looser';
        } else if (avgValidAnswers == 100) {
            $scope.userStatus = 'guru';
        } else {
            $scope.userStatus = 'poor';
        }
    }

}

Como podemos ver, hemos definido tres propiedades además de un método en nuestro modelo de datos:

  • questions: Listado de preguntas con sus respectivas respuestas que serán cargadas dinámicamente en nuestro documento HTML.
  • userStatus: Rango del usuario en función de las preguntas que se van respondiendo.
  • validAnswers: Representa el número de respuestas acertadas por el usuario.
  • validate: Valida una pregunta en función de la respuesta del usuario. Actualiza userStatus y validAnswers además del status del objeto question.

Si nos fijamos, el método validate, que será invocado cuando el usuario responda a una pregunta (lo veremos en el próximo punto), actualiza las propiedades validAnswers, userStatus y question.status. Los valores asignados a question.status (ok o error) están representados en una hoja de estilos del mismo modo que los valores «looser», «poor» y «guru» del estado del usuario. Esto hará que, cuando cambie el valor de estas propiedades, se cargue en el documento una regla distinta de la hoja de estilos con lo que el usuario apreciará un cambio en el documento.


Usuario con rango «looser»


Usuario con rango «poor»


Usuario con rango «guru»

4.3 Definiendo la vista y su vinculación con el modelo.

Pues ya lo único que queda es definir nuestro documento HTML como si fuese una plantilla, vincularla con nuestro modelo y hacer que AngularJS despligue su «magia».

<!DOCTYPE HTML>
<html ng-app>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    Cuestionario con AngularJS
    
    
    <link type="text/css" rel="stylesheet" href="css/test.css?09022013"/>
</head>
<body>

Ejemplo de cuestionario utilizando AngularJS

<img src="/wp-content/uploads/tutorial-data/img/AngularJS-logo.png" alt="AngularJS" class="logoAngularJS"/>

{{question.text}}

<input type="radio" ng-model="question.userAnswer" value="{{answer.id}}" name="question-{{question.id}}" id="answer-{{question.id}}-{{answer.id}}" ng-change="validate(question)"/>
Has acertado {{validAnswers}} de {{questions.length}}
</body> </html>

Pues lo que estamos viendo es todo lo que necesitamos para construir nuestra vista y que, además tenga un comportamiento dinámico. Expliquemos algunos puntos:

  • Línea 2: vemos que el tag html está marcado con la directiva ng-app. Lo que se está haciendo es definir el ámbito sobre el que AngularJS actuará. En nuestro ejemplo sería en todo el documento HTML.
  • Línea 11: vemos que el elemento div tiene una directiva ng-controller con valor igual a TestController. Con esto estamos definiendo el controlador que actuará sobre el elemento y sus nodos hijo. Si nos fijamos el valor «TestController» coincide con la función donde definimos las propiedades de nuestro modelo y su comportamiento. Para el que conozca JSF sería algo como configurar el Back Bean que hay detrás de la vista.
  • Línea 15: vemos que hay un div con una directiva ng-repeat. Lo que hacemos es repetir ese elemento div (y sus nodos hijo) por cada «question» que tenemos definidas en el modelo (propiedad questions). Además define una variable question (la pregunta concreta) que podrá ser utilizada en ese ámbito. Si nos fijamos en la siguiente línea, observamos que podemos acceder directamente a las propiedades de question (recordemos que es un elemento del modelo) mediante la sintaxis {{}}. En concreto obtenemos los valores de las propiedades status y text.
  • Línea 18: Observamos que se están pintando los elementos input (radio-buttons) que representan las posibles respuestas de un usuario a una pregunta. Con la directiva ng-model igual a question.userAnswer lo que hacemos es vincular el valor de este elemento, que si nos fijamos es el id de la respuesta, con la propiedad userAnswer que teníamos definida en las preguntas de nuestro modelo. Con esto, cuando el usario seleccione una pregunta, el id de la pregunta seleccionada se vinculará automáticamente con dicha propiedad.
  • Línea 20: en ese mismo elemento input definimos una directiva ng-change con valor igual a validate(question). Lo que haremos será invocar al método validate que definimos en el modelo cuando se seleccione una respuesta. Con esto actualizaremos el número total de respuestas acertadas (validAnswers) y el rango del usuario (userStatus). Este cambio en el modelo se verá automáticamente reflejado en la vista.

Pues con esto ya tendríamos nuestro cuestionario dinámico implementado con AngularJS :-).

VER EJEMPLO EN FUNCIONAMIENTO.

5. Referencias.


6. Conclusiones.

En este tutorial hemos visto cómo dinamizar nuestras páginas HTML en el lado del cliente con ayuda del framework Javascript: AngularJS. Este tipo de frameworks (algunos los llaman MVC, otros MVVM) nos permiten separar la lógica de presentación de la vista mediante la vinculación de datos del modelo con componentes HTML.

Bajo mi punto de vista, AngularJS proporciona dos grandes ventajas:

  • Separación de la lógica de presentación de la vista, de forma que el código Javascript es independiente al código HTML por lo que podríamos rehacer la vista sin necesidad de tener que tocar ni una sola línea de nuestra lógica de negocio. Además, nuestro código es extremadamente fácil testear ya que no dependemos de ningún contexto externo (es lógica pura).
  • Facilidad a la hora de manipular los elementos del DOM y sus propiedades. Esta es una tarea que, por norma general, es bastante tediosa y a medida que la lógica de presentación crece suele ser complicado escribir código que pueda mantenerse con facilidad. AngularJS simplifica mucho la labor en este sentido.

Espero que este tutorial os haya sido de ayuda. Un saludo.

Miguel Arlandy

marlandy@autentia.com

Twitter: @m_arlandy

10 COMENTARIOS

  1. Quisiera hacerte una pregunta por ahí si estás al tanto, esto pudiera usar en móviles? con phone gap por ejemplo? y que los controles de la vista puedan ir cambiando según los datos que tengo en la base de datos, es decir, en un momento dado necesito mostrar un cuadro de exto, en otro momento necesito mostrar, una lista, y así ir cambiando los controles según los datos que vienen de la base de datos.
    Siguiendo el ejemplo de la encuesta. Si en mi sistema cargo 5 preguntas, con tres opciones cada una, la aplicación móvil lea la base de datos y cargue las 5 preguntas y 3 check en cada una, y si cargo en el sistema otra encuesta con 4 preguntas y dos check en cada una, sólo me cargue en la vista las 4 preguntas nuevas y dos check en c/u en el móvil?

  2. Hola Pablo,
    Por supuesto que el ejemplo de la encuesta puedes aplicarlo a una aplicación con phonegap. Al final no es más que una aplicación web con determinados plugins para interactuar con el dispositivo. Lógicamente el ejemplo de este tutorial no accede a base de datos (no era el objetivo). Simplemente sería hacer las peticiones al servidor para que te devuelva los datos de las preguntas y respuestas.

    Saludos

  3. Hola Nankom, la forma en la que referirse a este tipo de frameworks es un tema bastante espinoso y hay mucho debate sobre ello. De todas formas, en el artículo no habrás leído en ningún momento que se esté refiriendo a AngularJS como un framework que implementa el patrón MVC. Al final, la idea es siempre la misma, separar la vista de la lógica de presentación.

  4. Hola Miguel, primero felicitarte por el tutorial, genial para comprender angulajs. Me gustaría hacerte una pregunta acerca de una duda que tengo, voy hacer frente a un proyecto en el cual me gustaría utilizar la lógica de angularjs, pero tengo duda en usar este framework debido a que ya ha salido angular2 y ahora todo el soporte para angularjs deje de existir. ¿qué alternativa propondrías?, he pensado en backbone, pero me cuesta encontrar información y no se si reacjs es lo que necesito.

  5. Increíble, y estupendo pude hacer toda una aplicación en base a este tutorial, felicidades.
    Ahora la pregunta, me decepciono muchísimo el ver el angular 2 que parecería no tener nada que ver con la transparencia y facilidad de programación del angular js.
    Me podrías decir cual es tu experiencia con angular 2, hiciste esta aplicación en angular 2? me recomiendas hacerla de nuevo o me voy a otro framework,

    gracias por tu fabuloso aporte .
    Pedrito Rod

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad