> For the complete documentation index, see [llms.txt](https://ajgallego.gitbook.io/ionic/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ajgallego.gitbook.io/ionic/capitulo_ejercicios_2.md).

# Ejercicios 2

En esta segunda sección de ejercicios vamos a continuar con el ejercicio de la biblioteca para añadirle la arquitectura de Angular y algunos componentes con contenido dinámico.

## Ejercicio 2.1 - Configuración, rutas y controladores (1 punto)

Vamos a modificar el fichero `js/app.js` para añadir las cuatro rutas de nuestra aplicación y los correspondientes controladores. Este archivo ya tendrá algo de código que viene incluido al crear la aplicación con Ionic, simplemente se crea el módulo principal (comprobar que se llame `starter`) y se inicializan algunos componentes necesarios para que funcione Ionic (dentro de la sección `.run`).

A continuación de este código vamos a añadir la configuración de la aplicación, en la siguiente tabla se muestra un resumen con todos los campos necesarios para que la creeis:

| *state*     | *url*        | *templateUrl*    | *controller*    |
| ----------- | ------------ | ---------------- | --------------- |
| home        | ''           | home.html        | homeCtrl        |
| author      | /author      | author.html      | authorCtrl      |
| curriculum  | /curriculum  | curriculum.html  | curriculumCtrl  |
| ibiblioteca | /ibiblioteca | ibiblioteca.html | ibibliotecaCtrl |

En este mismo fichero añadiremos los cuatro controladores. El controlador `homeCtrl` estará vacío. El controlador `authorCtrl` solo asignará al `$scope` un objeto como el siguiente (pero rellenado con los datos del autor correspondiente):

```javascript
$scope.author = {
    name: '',
    email: '',
    twitter: '',
    phone: ''
};
```

El controlador `curriculumCtrl` también asignará directamente al `$scope` un array con la lista de puestos ocupados. Esta lista la podéis rellenar con el contenido que ya teníais para esta pantalla:

```javascript
$scope.works = [
    { date: '', description: '' }, 
    { date: '', description: '' }, 
    { date: '', description: '' }
];
```

Y por último, el controlador `ibibliotecaCtrl` asignará al `$scope` un array con la lista de libros. Para obtener esta lista usaremos el servicio `bookService`, así que en primer lugar pegaremos el siguiente código al final de nuestro fichero `js/app.js` para definir dicho servicio:

```javascript
.factory('bookService', function() {
    var books = [
      { title: 'La colmena', year: '1951', author: 'Camilo José Cela Trulock', 
        isbn: '843992688X', editorial: 'Anaya', cover: 'lacolmena.jpg' },
      { title: 'La galatea', year: '1585', author: 'Miguel de Cervantes Saavedra', 
        isbn: '0936388110', editorial: 'Anaya', cover: 'lagalatea.jpg' },
      { title: 'El ingenioso hidalgo don Quijote de la Mancha', year: '1605', 
        author: 'Miguel de Cervantes Saavedra', 
        isbn: '0844273619', editorial: 'Anaya', cover: 'donquijote.jpg' },
      { title: 'La dorotea', year: '1632', author: 'Félix Lope de Vega y Carpio', 
        isbn: '847039360X', editorial: 'Anaya', cover: 'ladorotea.jpg' },
      { title: 'La dragontea', year: '1602', author: 'Félix Lope de Vega y Carpio', 
        isbn: '8437624045', editorial: 'Anaya', cover: 'ladragontea.jpg' }
    ];
    return {
        getBooks: function() {
            return books;
        },
        getBook: function(id) {
            return books[id];
        },
    }
})
```

Y para utilizarlo tenemos que inyectar el servicio en el nuevo controlador `ibibliotecaCtrl` y simplemente asignar los libros al `$scope` de la forma:

```javascript
$scope.books = bookService.getBooks();
```

## Ejercicio 2.2 - Página de inicio y *templates* (1 punto)

En este ejercicio vamos a actualizar las vistas para que todo funcione correctamente. Cada una de las páginas que habíamos creado en el ejercicio anterior (`author.html`, `curriculum.html` e `ibiblioteca.html`) las movemos dentro de la carpeta `templates`. Además añadimos la plantilla `home.html` que de momento estará vacía. De esta forma en la carpeta raíz nos habrá quedado solo el fichero `index.html`.

A continuación vamos a arreglar el contenido de las plantillas. Dentro de cada vista tendremos que dejar una estructura similar a la siguiente:

```markup
<ion-view title="Inicio">
    <ion-content class="padding">
        ...CONTENIDO ANTERIOR...
    </ion-content>
</ion-view>
```

El resto del contenido de la vista que teníamos lo eliminamos, quitamos todas las etiquetas HTML iniciales para la carga de dependencias, etc., y dejamos solamente el bloque de contenido marcado con `<ion-content>`. Las cabeceras también tendremos que eliminarlas, pero moveremos el título al atributo `title` de la directiva `ion-view` de cada vista. Para el template `home.html` moveremos el contenido que teníamos en `index.html` siguiendo estas mismas instrucciones. Y en `index.html` cambiaremos su sección `<body>` para que incluya únicamente las siguientes directivas:

```markup
<body ng-app="starter">
    <ion-nav-bar class="bar-positive">
        <ion-nav-back-button class="button-clear">
            <i class="ion-chevron-left padding-left"></i>
        </ion-nav-back-button>
    </ion-nav-bar>
    <ion-nav-view></ion-nav-view>
</body>
```

A continuación vamos a arreglar los enlaces que cambiaban de pantalla, en `home` teníamos dos y en `author` teníamos otro para ir a `curriculum`. Tenemos que eliminar el atributo `href` de estos enlaces y sustituirlo por `ui-sref` indicando el nombre del estado al que queremos ir, por ejemplo:

```markup
<a ui-sref="author" class="item item-icon-left">...</a>
```

Por último vamos a modificar las plantillas para que muestren el contenido que le hemos pasado desde el controlador a través de la variable `$scope`. En `author.html` mostraremos los valores directamente usando, por ejemplo, `{{author.name}}`. Para `curriculum.html` e `ibiblioteca.html` tendremos que crear un bucle que muestre todos los elementos del array y en cada uno de ellos genere una fila de la lista, por ejemplo:

```markup
<li class="item" ng-repeat="work in works">
    <p class="date">{{work.date}}:</p>
    <p>{{work.description}}</p>
</li>
```

## Ejercicio 2.3 - Pantalla vista detalle (1 punto)

Por último vamos a añadir una pantalla para mostrar la vista detalle de un libro de la biblioteca. Es decir, que al pulsar sobre un elemento de la lista se cambie a una nueva pantalla en la que se muestre la información ampliada de un libro.

Vamos a empezar definiendo la nueva ruta, la cual tendrá la siguiente configuración:

| *state*    | *url*     | *templateUrl* | *controller* |
| ---------- | --------- | ------------- | ------------ |
| bookDetail | /book/:id | book.html     | bookCtrl     |

A continuación vamos a crear el controlador `bookCtrl`, el cual tendrá que obtener el valor de `id` de los parámetros de entrada (revisa la sección sobre Controladores de la teoría). A partir del valor de `id` podemos recuperar los datos del libro usando el servicio `bookService` y asignarlo al `$scope` de la forma:

```javascript
$scope.book = bookService.getBook(id);
```

Por último tenemos que terminar las vistas para que todo funcione. En la vista que ya teníamos `ibiblioteca.html` vamos a modificar los elementos del listado para añadir un enlace a la pantalla detalle:

```markup
<div class="list">
  <a class="item item-thumbnail-left" ng-repeat="book in books" 
        ui-sref="bookDetail({id: $index})">
    ...
  </a>
</div>
```

Como se puede ver el enlace al estado `bookDetail` se ha creado usando el atributo `ui-sref` y pasándole como parámetro la variable `$index`. Esta variable contiene la posición del elemento actual en el array iterado.

En la nueva plantilla `book.html` mostraremos la información ampliada de un libro. A continuación se muestra una captura de como tendrá que quedar esta pantalla:

![](/files/-LwrBVpv7CQWenaxMgwl)
