Material‎ > ‎Software‎ > ‎Angular JS‎ > ‎

AngularJS - Ejemplo Proyecto Simple

Creando un proyecto simple con Angular

Vamos a ir construyendo una aplicación simple con un ejemplo. Nuestro objetivo es crear un proyecto simple al que vamos a llamar "libros-frontend-angular

 NOTA: El ejemplo que vamos a ver lo pueden descargar de:
 https://xp-dev.com/svn/uqbar/examples/ui/web/angular/libros-frontend-angular

Crear estructura

Para trabajar de forma prolija vamos a crear la siguiente estructura de directorios con los archivos (vacios por ahora):
  • libros-frontend-angular
    • app
      • css
        • app.css
      • js
        • app.js
        • controllers.js
      • lib
    • index.html

Conseguir Angular

Como es de esperarse para usar AngularJs necesitamos una version de la librería, en este ejemplos vamos a usar la version 1.2.9 (última versión estable al momento de escribir este ejemplo), lo podemos descargar de: https://code.angularjs.org/1.2.9/
Una vez que bajamos el archivo angular.js lo pegamos adentro de la carpeta lib.

Si bien así ya podemos empezar a trabajar, porque tanto HTML como Javascript solo requieren escribir código (no necesitamos un "compilador" ni nada por estilo), es altamente recomendable usar un buen editor de texto con autocomplete, syntax highlighting, etc. O sea, seguimos en el siglo 21 :)
Tiramos dos opciones acá

1) Instalarse los plugins de eclipse.
  • Ir a "Help->Install New Software..."
  • Buscar en el combo la URL de nuestra distribución de eclipse (Por ejemplo con eclipse Juno es "http://download.eclipse.org/releases/juno")
  • Buscar de entre todo el software los items:
    • "Eclipse Web Developer Tool"
    • "Eclipse Xml Editors and Tool", y 
    • "JavaScript Development Tools"
Lo bueno de esta opción es que mantienen el entorno de trabajo unificado. Es decir el eclipse tanto para el front-end como para el back-end.

2) La otra opción es instalarse uno de los nuevos editores para desarrollo web:
    

Integrar angular a nuestra pagina

Ya tenemos todo lo que necesitamos por ahora, entonces empecemos con nuestro ejemplo.
Vamos a arrancar con un Hello world! para ir extendiéndolo.
Para eso vamos a completar el archivo index.html:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Ejemplo de Libros en Angular</title>
</head>
<body>
    <p>Hola Mundo! </p>

</body>
</html>

Si abrimos el archivo con el browser (nos paramos sobre el archivo -> Abrir con -> <elija su browser favorito aquí>) vamos a ver una página (bastante fea) que dice Hola Mundo!

Hasta ahora todo muy lindo pero... ¿y angular? Claro... no lo estamos usando todavía, entonces agreguémoslo.

Para importar la librería simplemente tenemos que agregar el script que nos bajamos, esto lo podemos hacer con:
<script src="lib/angular.js"></script>

En nuestro ejemplo:
<!doctype html>
<html lang="en" >
<head>
  <meta charset="utf-8">
  <title>Ejemplo de Libros en Angular</title>
</head>
<body>
    <p>Hola Mundo! </p>

  <!-- Agregamos angular para que funcione  -->
  <script src="lib/angular.js"></script>
  
</body>
</html>

Ahora tenemos Angular disponible, entonces probemos algunos de los features que nos da angular.
En vez de escribir Hola Mundo, vamos a poner el resultado de hacer una cuenta (súper compleja) como por ejemplo 7 * 8. Como esto es muy complejo (?) vamos a dejar que se calcule y no poner 56.
De lo que vimos para hacer esto vamos a usar un template: {{7*8}}

<!doctype html>
<html lang="en" >
<head>
  <meta charset="utf-8">
  <title>Ejemplo de Libros en Angular</title>
</head>
<body>
    <p>{{7*8}}</p>

  <!-- Agregamos angular para que funcione  -->
  <script src="lib/angular.js"></script>
  
</body>
</html>
Pero si recargamos la pagina en vez de ver 56 vemos {{7*8}} ¿por qué?
Y... porque no le dijimos que esa parte ¡es un módulo de Angular! Entonces seguimos sin usarlo.
Cambiemos eso.

Primero vamos a decirle a angular que tiene jurisdicción en todo lo que esté dentro del tag html, y que particularmente nuestra aplicación se llama librosApp:
<html lang="en" ng-app="librosApp">

Para seguir el contrato que nos propone Angular tenemos que declarar nuestro módulo. Entonces para eso vamos a completar el archivo app.js solamente declarando nuestra aplicación:
'use strict';
angular.module('librosApp', [ ])

Por ahora nuestra app no tiene dependencias, con lo cual ponemos la lista vacía de dependencias

 OJO: ¡El nombre del modulo en app.js tiene que coincidir con el nombre que usamos en el html!

Lo único que nos falta es importar el archivo app.js desde nuestro template (index.html):
<!doctype html>
<html lang="en" ng-app="librosApp">
<head>
  <meta charset="utf-8">
  <title>Ejemplo de Libros en Angular</title>
  <link rel="stylesheet" href="css/app.css"/>
</head>
<body>
    <p>{{7*8}}</p>

  <!-- Agregamos angular para que funcione  -->
  <script src="lib/angular.js"></script>
  
  <!-- Importamos los archivos extras que vamos a usar -->
  <script src="js/app.js"></script>
</body>
</html>

¡Ahora sí! Si recargamos la pagina vemos 56

Saludando con nombre

En realidad es todo una excusa para usar un binding, pero lo que queremos hacer es volver al Hola Mundo pero personalizándolo más, vamos a agregar un input de forma que digamos Hola + <lo que ingresan en el input>.
Primero agreguemos el input, fácil:

<input />

Ahora cambiemos para que nos saluden, entonces escribimos:

<p>Hola  {{???}}</p>

Claro... ¿como referenciamos al valor que ingresaron? Y... por ahora no podemos porque no bindeamos el valor ingresado a ningún lado, entonces hagámoslo:

<input ng-model="nombre"/>

Y reemplazamos los signos de preguntas con el nombre de nuestra variable bindeada.

<!doctype html>
<html lang="en" ng-app="librosApp">
<head>
  <meta charset="utf-8">
  <title>Ejemplo de Libros en Angular</title>
  <link rel="stylesheet" href="css/app.css"/>
</head>
<body>
    <input ng-model="nombre"/> 
    <p>Hola  {{nombre}}</p>

  <!-- Agregamos angular para que funcione  -->
  <script src="lib/angular.js"></script>
  
  <!-- Importamos los archivos extras que vamos a usar -->
  <script src="js/app.js"></script>
  
</body>
</html>

Ya hicimos nuestro primer binding ahora hagamos la aplicación de los libros ;)

Mostrando una lista de libros

Todo muy lindo... pero nuestra aplicación era de libros y estamos saludando gente.
Es cierto, entonces dejemos de jugar con angular y mostremos los libros.
Lo primero que nos preguntamos es... ¿Qué es un Libro? Pensémoslo desde la vista y sobre lo que queremos ver, lo único que nos interesa de un libro es su Nombre y su Autor.
Lo que queremos mostrar es una lista con libros donde elemento nos dice el nombre del libro y el autor.
Pensemos que tenemos nuestros objetos felices y describamos la vista en html:

<ul>
    <li ng-repeat="libro in libros">
        {{libro.titulo}}
        <p>{{libro.autor}}</p>
    </li>
</ul>

Usamos un ng-repeat porque lo que queremos es decirle a angular que el elemento (li) se repite por cada libro en el conjunto de libros.

Pero, de algín lado tienen que surgir los libros, ademas por la idea que nos propone angular toda información se almacena adentro de un scope y cada scope pertenece a un controller. Entonces necesitamos definir todo lo que dijimos:
  • Un controller que contenga los datos que vamos a definir: lo vamos a llamar:  TodosLosLibrosCtrl. En controllers.js:
    angular.module('librosApp', []).controller('TodosLosLibrosCtrl', function () {

    });

  • Información de los libros a mostrar, por ahora vamos a definirlos nosotros. Luego lo reemplazaremos por una llamada al servidor. En controllers.js agregamos al scope la variable libros:
    angular.module('librosApp', []).controller('TodosLosLibrosCtrl', function ($scope) {
        $scope.libros = [
            {'titulo': 'The design of every day things', 'autor': 'Don Norman'},
            {'titulo': 'El nombre del viento', 'autor': 'Patrik Rufus'},
            {'titulo': 'Game of Thrones', 'autor': 'R.R. Martin'}
        ];
    });

  • Importar el archivo de controllers desde el index e incluir el controller como parte del body para que las variables sean visibles:
    <!doctype html>
    <html lang="en" ng-app="librosApp">
    <head>
      <meta charset="utf-8">
      <title>Ejemplo de Libros en Angular</title>
      <link rel="stylesheet" href="css/app.css"/>
    </head>
    <body ng-controller="TodosLosLibrosCtrl">
         <ul>
            <li ng-repeat="libro in libros">
                {{libro.titulo}}
                <p>{{libro.autor}}</p>
            </li>
        </ul>
      <!-- Agregamos angular para que funcione  -->
      <script src="lib/angular.js"></script>
      
      <!-- Importamos los archivos extras que vamos a usar -->
      <script src="js/app.js"></script>  
      <script src="js/controllers.js"></script>  
    </body>
    </html>

Si recargamos la pagina ¡vamos a ver la lista de libros!

Filtrando los resultados

Ahora tenemos una lista de libros, algo muy común que nos interesaría hacer con mucha información junta es filtrarla.

Entonces vamos a agregar un input text para ingresar un filtro:

<input ng-model="libroBuscado">

El valor que ingresamos ahi es el valor que queremos aplicar como filtro, para eso usamos lo que nos propone angular:

<li ng-repeat="libro in libros | filter:libroBuscado">
¡Y con esto ya podemos filtrar los resultados!

Transformando la lista en una tabla

Vamos a cambiar el componente para mostrar los resultados, ahora estamos usando una lista pero queremos cambiarlo a una tabla, entonces para eso el único cambio que necesitamos hacer es en el template.

El cambio es simple, partimos de una lista:

 <ul>
    <li ng-repeat="libro in libros | filter:libroBuscado">
        {{libro.titulo}}
        <p>{{libro.autor}}</p>
    </li>
</ul>

La parte mas "complicada" del asunto es pensar a qué item le vamos a poner el atributo ng-repeat, en el caso de la tabla lo que queremos es repetir cada fila por los telefonos que queremos ver, entonces va en el tr:

 <table>
    <tr ng-repeat="libro in libros | filter:libroBuscado">
        <td>{{libro.titulo}}<td>
        <td>{{libro.autor}}<td>
    </tr>
</table>

Ahora vemos la tabla pero para clarificar vamos a agregarle una fila con el título de la grilla:

    <table>
         <tr>
             <th>Titulo</th>
             <th>Autor</th>
         </tr>
        <tr ng-repeat="libro in libros | filter:libroBuscado">
            <td>{{libro.titulo}}</td>
            <td>{{libro.autor}}</td>
        </tr>
    </table>

Mejorando mínimamente la vista

Si vemos nuestra aplicación es particularmente fea, en si no tiene estilo alguno.

Vamos a agregarle un poco de estilos a la pagina.

Para esto es que agregamos el app.css y lo linkeamos desde el index.html con:

<link rel="stylesheet" href="css/app.css"/>

Para mejorar un poco la vista vamos a cambiar la fuenta de la página y remarcar los border, modificando los colores, vamos a incluir en nuestro app.css:

body{
    font-family: verdana,arial,sans-serif;
    font-size:11px;
}

.filtro{
    border: 1px solid #d0d0d0;
    border-color: #666666;
    width: 250px;
    margin-top: 10px;
    margin-bottom: 10px; 
    padding-top: 5px; 
    padding-bottom: 5px;
    padding-left: 5px;
    padding-right: 5px;
    background: #dedede;
}

.filtroLibros{
    width:200px;
}

.buscarLibros{
     font-weight: bolder;
}

.tablaLibros {
    color:#333333;
    border-width: 1px;
    border-color: #666666;
    border-collapse: collapse;
}
.tablaLibros th {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #666666;
    background-color: #dedede;
}
.tablaLibros td {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #666666;
    background-color: #ffffff;
}

Y a agregar las clases que estamos usando a los elementos que corresponden:

<!doctype html>
<html lang="en" ng-app="librosApp">
<head>
  <meta charset="utf-8">
  <title>Ejemplo de Libros en Angular</title>
  <link rel="stylesheet" href="css/app.css"/>
</head>
<body ng-controller="TodosLosLibrosCtrl">
    
    <div class="filtro">
        <span class="buscarLibros">Buscar:</span> 
        <input ng-model="libroBuscado" class="filtroLibros">
    </div> 

     <table class="tablaLibros">
         <tr>
             <th>Titulo</th>
             <th>Autor</th>
         </tr>
        <tr ng-repeat="libro in libros | filter:libroBuscado">
            <td>{{libro.titulo}}</td>
            <td>{{libro.autor}}</td>
        </tr>
    </table>
  <!-- Agregamos angular para que funcione  -->
  <script src="lib/angular.js"></script>
  
  <!-- Importamos los archivos extras que vamos a usar -->
  <script src="js/app.js"></script>  
  <script src="js/controllers.js"></script>  
</body>
</html>

Haciendo una llamada al server

//usar $http y el server que armó javi en Play

Testeando la aplicación

//quizás sea mucho y es mejor usar algun gestor de dependencias, pero estaria bueno mostrar algun test de vista aca.