Paso 2: Detalle libros, autores y editoriales.

URL: https://github.com/Uniandes-isis2603/frontstepbystep.git
Release: git checkout -f paso-2

Requerimientos Nuevos

  1. Ver el detalle de un libro
  2. Ver el detalle de un autor
  3. Ver el detalle de una editorial

También veremos que ya no hacemos uso de las colecciones json que teníamos en el paso anterior, ahora vamos a invocar los servicios REST que implementamos en el proyecto backstepbystep.

Aplicación

Cambios para tener en cuenta.

En este paso vamos a utilizar varios estados en el módulo books:

  • el estado booksList para listar los libros que implementamos en el paso_1.
  • un estado nuevo para ver el detalle de un libro.

Vamos a crear vistas distintas para cada estado como se muestra en la figura anterior. La parte del detalle del libro es una vista y la parte de la galería de los libros es otra vista.

Jerarquía de estados en el módulo bookModule

La siguiente figura muestra los estados de la aplicación. Cuando se lanza la aplicación en el navegador, desde la barra de Menú principal se puede acceder a la lista de todos los libros (estado booksList), acceder a la lista de autores (estado authorsList) y acceder a la lista de editoriales (estado editorialsList).

El módulo bookModule define dos estados que extienden un estado abstracto llamado books. La función de los estados abstractos es factorizar algunos elementos que compartirán sus estados hijos como variables y templates.

En la figura anterior el estado booksList y el estado booksDetail extienden el estado abstracto books. Note también que hay una flecha desde booksList hacia booksDetail para indicar que el usuario navegará desde la lista de libros hasta un estado donde muestra el detalle de un libro particular.

Estado abstracto books

El siguiente fragmento de código muestra la definición de los nuevos estados en el módulo bookModule.

En la línea 7 se define el estado abstracto books.

  • Para indicar que el estado es abstracto se utiliza la propiedadabstract: true
  • la url de los estados hijos empezará por la url del estado papá. Eneste caso /books.
  • la vista que se utiliza en este estado es mainView que fue definida en el index.html
  • el template asociado con mainView está definido en books.html. Este template define dos vistas: detailView y listView
  • los estados hijos utilizan las vistas anteriores.
var mod = ng.module("bookModule", ['ui.router']); mod.constant("booksContext", "api/books"); mod.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) { var basePath = 'src/modules/books/'; $urlRouterProvider.otherwise("/booksList"); $stateProvider.state('books', { url: '/books', abstract: true, views: { 'mainView': { templateUrl: basePath + 'books.html', controller: 'bookCtrl', controllerAs: 'ctrl' } } }) ...

Para indicar que los estados booksList y booksDetail están anidados dentro del estado abstracto books se utiliza el atributo:

parent: 'books'.

Template books.html del estado abstracto

El template define las dos nuevas vistas: una para el detalle (<div ui-view="detailView"></div>) y otra para la lista (<div ui-view="listView"></div>):

<div class="container-fluid"> <div class="row"> <div ui-view="detailView"></div> </div> <div class="row"> <div ui-view="listView"></div> </div> </div>

Cambios en el estado listar books

El código siguiente muestra la definición del estado booksList:

... $stateProvider.state('books', { url: '/books', abstract: true, views: { 'mainView': { templateUrl: basePath + 'books.html', controller: 'bookCtrl', controllerAs: 'ctrl' } } }).state('booksList', { url: '/list', parent: 'books', views: { 'listView': { templateUrl: basePath + 'books.list.html' } } }) ... }]);

Solo define la vista listView donde se va a desplegar el template que está definido en 'books.list.html'. Este template se llama igual que en el paso-1 pero se agregan instrucciones para que, debajo de la imagen, aparezcan los nombres de los autores del libro. Estso nombres son enlaces que al seleccionarlos llevará al usuario al esatdo de detalle del libro.

Note en la línea 10 del siguiente código del template para mostrar los libros, donde se incluye un ciclo sobre los autores del libro actual y donde se construye el enlace al estado del detalle del autor.

<div class="container-fluid"> <div class="row"> <div class="col-md-2" ng-repeat="book in booksRecords"> <div class="thumbnail"> <a ui-sref="bookDetail({bookId: book.id})"> <img class="img-responsive" ng-src='{{book.image}}' alt="{{book.name}}" /> </a> <div class="caption text-center"> <p>{{book.name}}</p> <p ng-repeat="author in book.authors"> <a ui-sref="authorDetail({authorId: author.id})" class="thumb">{{author.name}}</a> </p> </div> </div> </div> </div> </div>

Estado booksDetail

El siguiente es el código de la definición del estado bookDetail.

$stateProvider.state('books', {...}) .state('booksList',{...}) .state('bookDetail', { url: '/{bookId:int}/detail', parent: 'books', param: { bookId: null }, views: { 'listView': { templateUrl: basePath + 'books.list.html' }, 'detailView': { templateUrl: basePath + 'books.detail.html', controller: 'bookCtrl', controllerAs: 'ctrl' } } }); }]);

En la definición de este estado hay varias cosas importantes:

  • En el url se indica el parámetro id del libro url: '/{bookId:int}/detail'
  • Se define ese id del libro como parámetro del estado así podrá ser utilizado dentro del controlador.
param: { bookId: null }
  • Las vistas del estado tiene la lista y el detalle para que se vean ambas simultáneamente. La vista detailView tiene un template para mostrar el libro seleccionado el controlador asociado actualiza el valor del currentBook (variable que utiliza el template y que se inicializa en el controlador) con el valor pasado por parámetro.

Cambios al controlador de book bookCtrl

El controlador de book ahora incluye una función para recuperar un libro particular. EL código de esta función comienza en la línea 9 del siguiente código.

(function (ng) { var mod = ng.module("bookModule"); mod.constant("booksContext", "api/books"); mod.controller('bookCtrl', ['$scope', '$http', 'booksContext', '$state', function ($scope, $http, booksContext, $state) { $http.get(booksContext).then(function (response) { $scope.booksRecords = response.data; }); if (($state.params.bookId !== undefined) && ($state.params.bookId !== null)) { $http.get(booksContext + '/' + $state.params.bookId).then(function (response) { $scope.currentBook = response.data; }); } } ]); } )(window.angular);

Si el identificador único del libro que fue definido en el parámetro bookId si está definido y es diferente de null entonces se trae utilizando el servicio HTTP, la información completa de ese libro. Note que para que el parámetro sea recuperable en el controlador, este tuvo que haberse guardado en los parámetros del estado. La expresión completa en el controlador es:

$state.params.bookId

Ver el detalle de un autor

Requerimientos Nuevos

  1. Ver el detalle de un autor
  2. Ver la lista de libros de un autor

Cambios importantes

  1. Crear el nuevo estado de detalle en el módulo autor
  2. Conectar el módulo autor con los libros para desplegar, con el detalle del autor, la lista de los libros propios del autor.

Estados del módulo authorModule

La nueva configuración de estados del módulo authorModule es similar a la de bookModule del paso anterior. Se define:

  1. Un estado abstracto authors
  2. Un estado para listar los autores authorsList
  3. Un estado para el detalle del autor authorsDetail

El cambio principal está en el estado authorsDetail que define dos vistas:

  1. la vista de detalle (similar a la de book)
  2. la vista de lista que muestra los libros del autor. En este caso, el controlador de la lista de books recibe de parámetro el autor seleccionado authorId. Este valor es utilizado en el template de books.list.html para filtrar los libros que se muestran. Note que para mostrar los libros del autor utilizamos el mismo template 'books.list.html' pero el controlador ahora es authorCtrl.

    Estado authorsDetail

$stateProvider.state('authors', {...}) .state('authorsList', {...}) .state('authorDetail', { url: '/{authorId:int}/detail', parent: 'authors', param: { authorId: null }, views: { 'listView': { templateUrl: basePathBooks + 'books.list.html', controller: 'authorCtrl', controllerAs: 'ctrl' }, 'detailView': { templateUrl: basePath + 'authors.detail.html', controller: 'authorCtrl', controllerAs: 'ctrl' } } });

Ver el detalle de una editorial

Para ver el detalle de la Editorial se comporta de la misma manera que con el detalle del autor y los libros.

results matching ""

    No results matching ""