AngularJS

Introducción

AngularJS es una extensión de HTML con nuevos atributos, es ideal para aplicaciones de una sola página (SPA's).

HTML es fantástico para documentos estáticos, pero no lo es para documentos cuyo contenido es dinámico en aplicaciones Web. AngularJS permite extender el vocabulario de HTML para el desarrollo de una aplicación Web, el resultado es un ambiente extraordinariamente expresivo, leíble y fácil de desarrollar.

AngularJS es fácil de aprender.

Si se utiliza JavaScript para desarrollar un sitio dinámico, AngularJS es una buena opción.

Agregar AngularJS

AngularJS es una JavaScript framework, es una biblioteca escrita en JavaScript. Es distribuido como un archivo JavaScript y puede ser añadido a una página con la etiqueta script.


  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
      

AngularJS extiende HTML con directivas ng. La directiva ng-app define una aplicación AngularJS, la directiva ng-model une los valores de controles HTML a los datos de una aplicación. La directiva ng-bind une los datos de una aplicación a la vista de HTML.

Ejemplo 1.


  <!DOCTYPE html>
  <html>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    <body>
      <div ng-app="">
        <p>Ingrese algo en la caja:</p>
        <p>Algo: <input type="text" ng-model="nombre"></p>
        <p ng-bind="nombre"></p>
      </div>
    </body>
  </html>
      

AngularJS inicia automáticamente cuando la página se termina de cargar. La directiva ng-app le dice a AngularJS que el elemento <div> es el dueño de la aplicación AngularJS. La directiva ng-model une los valores del campo de entrada a la variable de la aplicación nombre. La directiva ng-bind une el innerHTML del elemento <p> a la variable de la aplicación nombre.

Como pudo ver, las directivas AngularJS son atributos HTML con el prefijo ng. La directiva ng-init inicializa las variables de la aplicación.

Nota: Aunque es común ubicar los scripts al final de <body>, se recomienda cargar la biblioteca de AngularJS ya sea en <head> o bien al inicio de <body>. Esto es debido a que las llamadas a angular.module solo pueden ser compiladas posteriormente a que la biblioteca haya sido cargada.

Ejemplo 2.


  <!DOCTYPE html>
  <html>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    <body>
      <div ng-app="" ng-init="nombre='Juan'">
        <p>El nombre es <span ng-bind="nombre"></span></p>
      </div>
    </body>
  </html>
      

Expresiones AngularJS

AngularJS une datos y HTML utilizando expresiones.

Las expresiones de AngularJS se escriben entre llaves dobles: {{ expresion }}, sin embargo también pueden ser escritas dentro de una directiva ng-bind="expresion".

AngularJS procesará la expresión y devolverá el resultado exactamente donde la expresión fue escrita. Dichas expresiones, tal como en JavaScript, pueden contener caracteres, operadores y variables. Por ejemplo: {{ 5 + 5 }} o {{ nombre + " " + apellido }}.

Ejemplo 3. Expresiones AngularJS


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 3</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>
    <div ng-app="">
      <p>He aprendido a sumar: {{ 5 + 5 }}</p>
    </div>
  </body>
  </html>
      

Naturalmente si se quita el atributo ng-app="" del <div> contenedor de la aplicación, no se realizará la operación matemática y simplemente se imprime la expresión como texto.

Es importante mencionar que el atributo ng-app="" puede colocarse en otras etiquetas HTML, y no necesariamente en un <div>. En los ejemplos se utiliza un <div> como un contenedor de la aplicación.

Ejemplo 4. Cambiar atributos CSS


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 4</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>
    <p>AngularJS procesa la expresión y devuelve el resultado.</p>
    <p>El color de fondo del parrafo será cualquiera que se escriba en la caja de texto.</p>
    <div ng-app="" ng-init="colorFondo='white'; colorTexto='black'">
      <p>Color del texto: <input ng-model="colorTexto"></p>
      <p>Color del fondo: <input ng-model="colorFondo"></p>
      <h1 style="text-align:center; color:{{colorTexto}}; background-color:{{colorFondo}}">
        Mis colores son dinámicos gracias a AngularJS.
      </h1>
    </div>
  </body>
  </html>
      

Los números en AngularJS son como los números en JavaScript.

Ejemplo 5. Operaciones aritméticas


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 5</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>
    <h1>Calculadora</h1>
    <div ng-app="" ng-init="x=1; y=5">
      <p>x = <input type="number" ng-model="x"></p>
      <p>y = <input type="number" ng-model="y"></p>
      <p>x + y = {{ x + y }}</p>
    </div>
  </body>
  </html>
      

Ejemplo 6. Manejo de cadenas


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 6</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>
    <h1>Registro</h1>
    <div ng-app="" ng-init="nombre='Juan'; apellido='Perez'">
      <p>Nombres = <input ng-model="nombre"></p>
      <p>Apellidos = <input ng-model="apellido"></p>
      <p>Su nombre es: {{ nombre + " " + apellido }}</p>
    </div>
  </body>
  </html>
      

Ejemplo 7. Objetos


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 7</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>
    <h1>Registro</h1>
    <div ng-app="" ng-init="persona={nombre:'Juan', apellido:'Perez', edad:'18'}">
      <p>Nombre: <input ng-model="persona.nombre"></p>
      <p>Apellido: <input ng-model="persona.apellido"></p>
      <p>Edad: <input type="number" ng-model="persona.edad"></p>
      <p>Su nombre es {{ persona.nombre + " " + persona.apellido }} y tiene {{ persona.edad }} años.</p>
    </div>
  </body>
  </html>
      

Ejemplo 8. Arreglos


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 8</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>
    <h1>Registro</h1>
    <div ng-app="" ng-init="puntos=[1,10,56,20]">
      <p>El tercer valor en el arreglo es {{ puntos[2] }}</p>
    </div>
  </body>
  </html>
      

Tal como JavaScript, AngularJS puede contener expresiones con caracteres, operadores y variables.

A diferencia de las expresiones JavaScript, las expresiones AngularJS se pueden escribir dentro de HTML.

Las expresiones de AngularJS no contienen condicionales, ciclos y excepciones.

Las expresiones de AngularJS soportan filtros, mientras que las expresiones de JavaScript no.

Módulos en AngularJS

Los módulos en AngularJS definen una aplicación. Los módulos son contenedores de diferentes partes de una aplicación. El modulo es el contenedor de los controles de la aplicación.

Sintaxis

Un modulo se crea utilizando la función angular.module.


  <div ng-app="miApp">...</div>
  <script>
    var app = angular.module("miApp", []);
  </script>
      

El parámetro miApp se refiere a un elemento HTML en el cual la aplicación se ejecutará. Dicha aplicación en AngularJS puede contener contoles, directivas y filtros entre otros.

Nota: El parámetro [] en la declaración del modulo se utiliza para definir módulos dependientes. Si no se incluye el parámetro [], no se crea un nuevo modulo, en realidad se recupera uno ya existente.

Módulos y Controladores en Archivos Externos

En las aplicacipnes AngularJS es común colocar los módulos y controladores en archivos externos de JavaScript. La razón de esto es para conseguir un código más limpio y fácil de leer.

En el siguiente ejemplo, myApp.js contiene la definición de un modulo y el archivo myCtrl.js contiene el controllador.

Ejemplo 9. Modulo y Controladores en archivos externos


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 9</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>
    <h1>Modulo y Controlador Externos</h1>
    <div ng-app="myApp" ng-controller="myCtrl">
      {{ firstName + " " + lastName }}
    </div>

    <script src="myApp.js"></script>
    <script src="myCtrl.js"></script>
  </body>
  </html>
      

Directivas

AngularJS tiene un conjunto de directivas las cuales pueden utilizarse para añadir funcionalidad a una aplicación. Si desea ver una referencia completa de ellas, puede consultarlas aquí.

Adicionalmente, se puede utilizar angular.module para añadir directivas a una aplicación.

Las directivas en AngularJS son extensiones de atributos HTML que tienen el prefijo ng-.

Ejemplo 10. Directivas


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 10</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>
    <h1>Directiva</h1>

    <div ng-app="" ng-init="nombre='Juan'">
      <p>Ingrese algo:</p>
      <p>Nombre: <input type="text" ng-model="nombre"></p>
      <p>Usted escribió: {{ nombre }}</p>
    </div>

  </body>
  </html>
      

Enlace de Datos

La expresión {{ nombre }} en el ejemplo, es una expresión de enlace de datos de AngularJS. El enlace de datos permite unir expresiones de AngularJS con datos de AngularJS. {{ nombre }} está unida con ng-model="nombre".

Repetir Elementos HTML

La directiva ng-init permite repetir un elemento HTML.

Ejemplo 11. Repetir elementos HTML.


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 11</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>

    <div ng-app="" ng-init="nombres=['Juan','Pedro','Pablo', 'Luis']">
      <p>Repitiendo elementos HTML con <code>ng-repeat</code>:</p>
      <ul>
        <li ng-repeat="x in nombres">
          {{ x }}
        </li>
      </ul>
    </div>

  </body>
  </html>
      

La directiva ng-repeat clona los elementos HTML para cada elemento en el arreglo. También puede utilizarse en un arreglo de objetos.

Ejemplo 12. Repetir elementos HTML en un arreglo de objetos.


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 12</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>

    <div ng-app="" ng-init="names=[
      {name:'Jani',country:'Norway'},
      {name:'Hege',country:'Sweden'},
      {name:'Kai',country:'Denmark'}]">
      <p>Repetiendo elementos HTML con un arreglo de objetos:</p>
      <ul>
        <li ng-repeat="x in names">
        {{ x.name + ', ' + x.country }}</li>
      </ul>
    </div>

  </body>
  </html>
      

Directiva ng-app

La directiva ng-app define el elemento raíz de una aplicación AngularJS. Esta directiva inicializará automáticamente la aplicación cuando la página haya sido cargada.

Directiva ng-init

La directiva ng-init define valores iniciales para la aplicación AngularJS. Normalmente no se utiliza esta directiva, en su lugar es mejor utilizar un controlador o modulo para la misma función.

Directiva ng-model

La directiva ng-model enlaza los valores de los controles HTML (input, select, textarea, etc.) a los datos de la aplicación. La directiva ng-model puede además:

Crear nuevas directivas

Adicionalmente a las directivas existentes en AngularJS, el usuario puede crear sus directivas. Las nuevas directivas pueden crearse utilizando la función .directive.

Para invocar una nueva directiva se puede utilizar:

Los nombres de las directivas deben escribir con la primer letra en mayúscula (excepto la primer palabra), miPrimerDirectiva, y al invocarla se deben separadar con - y utilizar solo minúsculas, mi-primer-directiva.

Ejemplo 13. Crear nueva directiva, invocar por nombre de elemento HTML.


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 13</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body ng-app="myApp">

    <mi-primer-directiva></mi-primer-directiva>

    <script>
      var app = angular.module("myApp", []);
      app.directive("miPrimerDirectiva", function() {
          return {
              template : "<h1>!Fui concebido dentro de una directiva!</h1>"
          };
      });
    </script>

  </body>
  </html>
      

Ejemplo 14. Crear nueva directiva, invocar por atributo.


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 14</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body ng-app="myApp">

    <div mi-primer-directiva></div>

    <script>
      var app = angular.module("myApp", []);
      app.directive("miPrimerDirectiva", function() {
          return {
              template : "<h1>!Fui concebido dentro de una directiva!</h1>"
          };
      });
    </script>

  </body>
  </html>
      

Ejemplo 15. Crear nueva directiva, invocar por clase.


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 15</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body ng-app="myApp">

    <div class="mi-primer-directiva"></div>

    <script>
      var app = angular.module("myApp", []);
      app.directive("miPrimerDirectiva", function() {
          return {
              restrict: "C",
              template : "<h1>!Fui concebido dentro de una directiva!</h1>"
          };
      });
    </script>

    <p><b>Nota: </b>Se debe agregar el valor en la propiedad de resticción "C"
      para que sea posible invocarlo por el nombre de la clase.</p>

  </body>
  </html>
      

Ejemplo 16. Crear nueva directiva, invocar por comentario.


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 16</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body ng-app="myApp">

    <!-- directive: mi-primer-directiva -->

    <script>
      var app = angular.module("myApp", []);
      app.directive("miPrimerDirectiva", function() {
          return {
              restrict: "M",
              replace: true,
              template : "<h1>!Fui concebido dentro de una directiva!</h1>"
          };
      });
    </script>

    <p><b>Nota: </b> Se agrega la propiedad <b>replace</b>para que el comentario
      sea reemplazado y visible.</p>
    <p><b>Nota: </b> Se debe añadir el valor "M" a la propiedad <b>restrict</b>
      para que poder invocar la directiva desde un comentario.</p>
  </body>
  </html>
      

Controladores

Las aplicaciones AngularJS se manipulan con controladores. La directiva ng-controller define el controlador de la aplicación.

Para añadir un controlador a la aplicación y referir al controlador se utiliza la directiva ng-controller.

Ejemplo 17. Modulo y controlador


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 17</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>
    <h1>Controlador</h1>
    <div ng-app="miApp" ng-controller="miControl">
      {{ nombre + apellido }}
    </div>
    <script>
      var app = angular.module("miApp", []);
      app.controller("miControl", function($scope) {
        $scope.nombre = "Juan";
        $scope.apellido = "Perez";
      });
    </script>
  </body>
  </html>
      

La aplicación AngularJS se define como ng-app="miApp". La aplicación corre dentro de <div>. El atributo ng-controller="miControl" es una directiva AngularJS que define un controlador, es una función JavaScript.

AngularJS invocará el controlador mediante el objeto $scope, en AngularJS $scope es la aplicación objeto (el dueño de las variables de la aplicación y las funciones).

El controlador crea dos propiedades (variables) en el scope (nombre y apellido).

La directiva ng-model une los campos de entrada de las propiedades del controlador (nombre y apellido).

Metodos controladores

En el ejemplo anterior se mostró un objeto controlador con dos propiedades. Un controlador puede tener métodos (variables y funciones).

Ejemplo 18. Métodos en controladores


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 18</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>

    <div ng-app="miApp" ng-controller="personaCtrl">
      Nombre: <input type="text" ng-model="nombre"><br>
      Apellido: <input type="text" ng-model="apellido"><br>
      <br>
      Nombre Completo: {{nombreCompleto()}}
    </div>

    <script>
      var app = angular.module('miApp', []);
      app.controller('personaCtrl', function($scope) {
          $scope.nombre = "Juan";
          $scope.apellido = "Pérez";
          $scope.nombreCompleto = function() {
              return $scope.nombre + " " + $scope.apellido;
          };
      });
    </script>
  </body>
  </html>
      

Controladores en archivos externos

En aplicaciones extensas, es común almacenar los controladores en archivos externos. El manejo es similar al código JavaScript, por lo que solo es necesario copiar el código contenido en la etiqueta <script> en un archivo externo llamado por ejemplo personaCtrl.js.

Ejemplo 19. Controlador en un archivo externo

HTML


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 19</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>

    <div ng-app="miApp" ng-controller="personaCtrl">
      Nombre: <input type="text" ng-model="nombre"><br>
      Apellido: <input type="text" ng-model="apellido"><br>
      <br>
      Nombre Completo: {{nombreCompleto()}}
    </div>

    <script src="personaCtrl.js"></script>
  </body>
  </html>
      

AngularJS


  var app = angular.module('miApp', []);
  app.controller('personaCtrl', function($scope) {
      $scope.nombre = "Juan";
      $scope.apellido = "Pérez";
      $scope.nombreCompleto = function() {
          return $scope.nombre + " " + $scope.apellido;
      };
  });
      

Para el siguiente ejemplo se creará un nuevo archivo controlador y se utilizará en la aplicación.

Ejemplo 20. Otro controlador en archivo externo

HTML


  <!DOCTYPE html>
  <html lang="es">
  <head>
    <meta charset="UTF-8">
    <title>Ejemplo 20</title>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  </head>
  <body>
    <div ng-app="miApp" ng-controller="controladorNombres">
     <ul>
       <li ng-repeat="x in nombres">
         {{ x.nombre + ', ' + x.pais }}
       </li>
     </ul>
   </div>
   <script src="controladorNombres.js"></script>
  </body>
  </html>
      

AngularJS


  angular.module('miApp', []).controller('controladorNombres', function($scope) {
     $scope.nombres = [
         {nombre:'Jani',pais:'Norway'},
         {nombre:'Hege',pais:'Sweden'},
         {nombre:'Kai',pais:'Denmark'}
     ];
  });