Hoy vamos a realizar una introducción a Angular.js
¿Qué es Angular.js?
Si vamos a WikiPedia, podemos leer que AngularJS es un framework de JavaScript de código abierto, mantenido por Google, para desarrollar aplicaciones cliente de una sola página. Su objetivo es aumentar las aplicaciones basadas en navegador con capacidad de Modelo Vista Controlador (MVC), en un esfuerzo para hacer que el desarrollo y las pruebas sean más fáciles.
En resumen, AngularJS es un framework Javascript que nos permite añadir interactividad a HTML, agilizando nuestro desarrollo.
Incluyendo Angular.js
Nos descargamos la librería angular.js, y la incluímos en el body de nuestro HTML:
<!DOCTYPE html>
<html>
<head>...
</head>
<body>
<script type="text/javascript" src="angular.min.js"></script>
</body>
</html>
Módulos
Los módulos son piezas de nuestra aplicación Angular donde escribimos el código, y que nos permite un código más fácil de mantener, testear y leer.
Además, nos permite estructurarlos de forma modular, de manera que un módulo puede depender de otros módulos.
Creámos un módulo, encapsulado dentro de una función de javascript, llamando al método module de JS, del siguiente modo:
(function() {
var app = angular.module('miModulo', [dependencia1, dependencia2, ...]);
})();
Para poder acceder a nuestro módulo, deberemos cargarlo también como JS, por lo que debemos referenciar la página JS donde está nuestro módulo, a continuación de la referencia al JS de angular, así como incluir la directiva del módulo, como veremos más adelante en Directivas.
<!DOCTYPE html>
<html ng-app="miModulo">
<head>...
</head>
<body>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
Una vez hemos vinculado una aplicación a nuestro HTML, podremos empezar a utilizar expresiones dentro del mismo.
Expresiones
Las expresiones es la forma que tenemos de insertar valores dinámicos en nuestro HTML.
{{ var }}
Por ejemplo:
<strong>{{ "Hola " + "mundo" }}</strong>
Producirá el resultado: Hola mundo
Las expresiones definen una relación de data-binding bi-direccional, es decir, cuando una propiedad cambia, las expresiones que la usan son re-evaluadas.
Directivas
Una directiva es un marcador en una etiqueta HTML, que le dice a Angular que ejecute o referencie determinado código JS:
- ng-app Vincula el modulo de la aplicación a la página
<html ng-app="miaplicacion">
Desde el lado Javascript, crearemos nuestra aplicación con el método module de angular:
var app = angular.module('miApp', []);
- ng-controller Vincula una función controlador a la página
<body ng-controller="MiControlador as miAlias">
Desde el lado javascript, definiremos nuestro controlador con el método controller de angular, de la siguiente forma:
app.controller("MiControlador", function(){
//contenido del controlador...
});
- ng-show/ng-hide muestra o esconde la sección en función de una expresión
<h1 ng-show="miAlias.visible"> Hola, {{ name }} </h1>
- ng-repeat Repite una sección para cada ítem en un array
<li ng-repeat="user in miAlias.users"> {{user.name}} </li>
- ng-src Carga una imagen a partir de una expresión
<img ng-src="{{miAlias.user.images[0].fullImg}}" />
- ng-click Añade interactividad a un elemento clickable
- ng-init Nos permite evaluar una expresión en el scope actual
<div ng-init="variable = 5">
<a href ng-click="variable = 1">texto enlace 1</a>
<a href ng-click="variable = 2">texto enlace 2</a>
<strong>{{variable}}</strong>
...
De este modo, de entrada “variable” valdrá 5.
Al llamar el código de ng-click, estamos actualizando a tiempo real el valor de “variable”, y actualizando la expresión {{variable}}
- ng-class Determina si un elemento dispone de una clase en función de una expresión
<div ng-class="{ clase1:variable === 2}" />
Este código añadirá la clase “clase1” a el div únicamente en el caso de que el valor de variable sea 2
- ng-model Permite vincular el valor de un elemento de formulario a una propiedad
<input ng-model="miVariable" />
Por ejemplo, podemos ver como realizaríamos una preview en un formulario para valorar una aplicación, del siguiente modo:
<form name="reviewForm">
<!-- Live Preview -->
<blockquote>
<strong>{{review.stars}} Stars</strong>
<strong>{{review.comment}} Stars</strong>
</blockquote>
<!-- Review Form -->
<h4>Submit a Review</h4>
<fieldset class="form-group">
<select class="form-control" ng-model="review.stars"
ng-options="stars for stars in [5,4,3,2,1]" title="Stars">
<option value="">Rate the Application</option>
</select>
</fieldset>
<fieldset class="form-group">
<textarea class="form-control" ng-model="review.comment"
placeholder="Write your opinion about the app..." title="Review"></textarea>
</fieldset>
</fieldset>
<fieldset class="form-group">
<input type="submit" class="btn btn-primary pull-right" value="Submit Review" />
</fieldset>
</form>
- ng-submit Nos permite llamar a una funcion JS al hacer submit de un formulario. Cabe destacar que este marcador va en la etiqueta < form >.
<form ng-submit="miControlador.miMetodo(miArg)" />
Este código añadirá la clase “clase1” a el div únicamente en el caso de que el valor de variable sea 2
Filtros
Los filtros són funciones que actuan sobre unos ciertos datos para cambiar su resultado. El modo de usar los filtros, es a través de una pipe, siguiendo el estilo:
{{ miVariable | filtro:opciones }}
Los filtros habituales que podemos encontrar son:
- date Formatea la entrada siguiendo una estructura de fecha
{{'1388123412323' | date:'MM/dd/yyyy @ h:mma'}} -> 12/27/2013 @ 12:50AM
- uppercase/lowercase Formatea la entrada a Mayúsculas/Minúsculas
{{'hola mundo' | uppercase}} -> HOLA MUNDO
- limitTo Limita la salida a un número concreto de elementos (para arrays)
{{'hola mundo' | limitTo:5}} -> hola m
<li ng-repeat="user in miAlias.users | limitTo:2"> -> muestra los 2 primeros usuarios
- orderby Ordena la salida de elementos (para arrays)
<li ng-repeat="user in miAlias.users | orderBy:'-name'">
El – delante implica orden descendiente
Formularios
Angular incorpora algunas propiedades muy útiles por defecto en los formularios.
De entrada, tiene un mecanismo de validación automático de los campos. Es recomendable, no obstante, desactivar primero la validación automática de HTML, por si la tuviera, con el atributo novalidate.
Entre los elementos que podemos validar, tenemos:
- e-mails
- urls
- números (además podemos definir min y max)
Ponemos el siguiente formulario como ejemplo:
<form name="reviewForm" ng-controller="FormController as formCtrl"
ng-submit="reviewform.$valid && formCtrl.someMethod()" novalidate>
<input name="user" ng-model="formCtrl.user" type="email" required />
<input type="submit" class="btn btn-primary pull-right" value="Submit Review" />
</form>
Veamos los detalles:
-
nombreFormulario.$valid: Angular crea una variable con el form name que hemos definido, a la que le añade automáticamente la propiedad valid (a la que podemos acceder con el símbolo $ delante). De este modo podemos controlar si llamamos al método submit o no.
-
novalidate: Como ya hemos comentado, usamos este marcador en la etiqueta form para evitar validaciones de HTML, ya que queremos usar la validación de Angular.
-
required: Al añadir este marcador a un input, el formulario será inválido en caso de que este campo quede vacío, o esté mal completado (en caso de email, por ejemplo, se asegura de que la estructura de la dirección de email sea correcta).
Clases automáticas en función de la validación
Angular, además de comprobar si un campo es válido o no, cambia sus clases en función del contenido. Veamos que sucede en el caso de un input type=”email”:
- Si el campo está vacio, le añade:
<input name="user" type="email" ... class="ng-pristine ng-invalid" />
- Si escribimos un email incorrecto:
<input name="user" type="email" ... class="ng-dirty ng-invalid" />
- Si escribimos un email válido:
<input name="user" type="email" ... class="ng-dirty ng-valid" />
Con estas útiles clases, podemos indicar al usuario la validez de los campos añadiendo un sencillo CSS como el siguiente:
.ng-invalid.ng-dirty{
border-color: red;
}
.ng-valid.ng-dirty{
border-color: green;
}
Por hoy es suficiente, espero ir profundizando un poquito más en los detalles de Angular.js en breve. ¡Saludos!