editoriallist - keblato/TutorialesTalleres-Angular GitHub Wiki

Desplegar una Lista de Editoriales

Código está https://editorial-list.stackblitz.io
Video: Intro Ejemplo

Objetivos

En este ejemplo vamos a crear un módulo funcional llamado EditorialModule que tendrá un componente que se ocupa de listar las editoriales. Al ejecutar el ejemplo vamos a obtener el siguiente despliegue:

editoriales

El ejemplo muestra:

  • La definición del nuevo módulo y cómo este es importando en el módulo principal
  • La definición del nuevo módulo y cómo se define y exporta el componente, cómo provee el servicio.
  • La definición de un servicio y el uso de http para obtener la lista de editoriales.
  • El concepto de Observable y subscribe
Ir al inicio

Diseño

Video: Diseño global

En este ejemplo tenemos dos módulos: AppModule que es el módulo principal y EditorialModule que es un módulo que contendrá las distintas funcionalidades que se le ofrecerán al usuario, para manipular el recurso editorial. En este ejemplo, el módulo EditorialModule solo contiene un componente que se ocupa de desplegar en una lista las editoriales que existen.

El siguiente diagrama muestra los elementos de la solución:

listar editorial

Elemento Responsabilidad
AppModule Es una clase anotada con @NgModule. Representa el módulo principal de la aplicación. Declara el componente AppComponent e importa dos módulos de angular BrowserModule, que provee servicios para todas las aplicaciones angular y HttpClientModule que provee servicios para hacer llamados http (lo vamos a usar para obtener las editoriales get editorials. También importa EditorialModule
AppComponent Es una clase anotada con @Component. Representa el componente principal de la aplicación. Define en la anotación el selector app-root y los archivos html y css del template y de los estilos de este componente. Si vemos el index.html este utiliza el selector de este componente principal.
<body>
	<app-root></app-root>
</body>
Elemento Responsabilidad
EditorialModule Es una clase anotada con @NgModule. Representa el módulo para los requerimientos del recurso editorial. Declara y exporta el componente EditorialListComponent, provee el servicio EditorialService e importa el módulo de angular CommonModule
EditorialListComponent Es una clase anotada con @Component. Representa el componente que se encarga de listar las editoriales.
Define en la anotación el selector list-editorial y los archivos html y css del template y de los estilos de este componente. Si vemos el app-component.html este utiliza el selector de este componente: <list-editorial></list-editorial>.
El constructor del componente recibe el servicio que se ocupa de traer las editoriales.
Define un método que utiliza el servicio y deja las editoriales en un arreglo Editorial[].
Editorial Es una interface que define el tipo Editorial que es una tupla de dos atributos: id: number y name: string
EditorialService Es el servicio que va a utilizar http para acceder a la colección de editoriales. Explicación detallada más adelante.
Video: Componente

La siguiente figura muestra la relación de los distintos elementos en las vistas o templates html. En ejecución, primero se carga el archivo index.html que contiene el selector app-root. Este selector está definido en el componente AppModule. app-root es remplazado por el contenido del template de AppModule que en este ejemplo consiste del selector list-editorial. Este, a su vez, está definido en el componente EditorialListComponente. Finalmente list-editorial es remplazado por el contenido del template de EditorialListComponente que se ocupa del despliegue de la lista.

  • Las flechas azules muestran el remplazo de los templates/vistas.
  • Las flechas anaranjadas muestran en dónde se define el selector y en dónde se usa
  • Las flechas moradas muestran en dónde se declara el template/vista y en qué archivo está contenido

listar

Ir al inicio

EditorialService

Los servicios son los elementos de la aplicación que se encargan de realizar lógica funcional. En particular, habrá servicios para comunicar a los componentes de la aplicación front con la aplicación que se encuentra en algún servidor para pedir/recibir aquello que se va a mostrar, o para realizar las transacciones.

Si la aplicación exterior tiene un API REST, el servicio se ocupará de hacer la invocación construyendo la URL que se necesite y enviando/recibiendo los objetos que se requieran.

Para simplificar, en este ejemplo, nuestro servicio no se conecta a un API REST para obtener las editoriales sino que las obtendrá de un archivo local llamado editoriales.json. Sin embargo, utilizaremos el módulo Angular de HttpClient pero la url será la ruta donde se encuentra el archivo json.

Inyección de dependencias en Angular

Referencia: dependency-injection

Las dependencias son servicios u objetos que una clase necesita para realizar su función. En Angular, se debe declarar la dependencia utilizando una anotación, y el framework la inyectará cuando construya el objeto; en el constructor se debe indicar como parámetro la dependencia.

En nuestro ejemplo, nuestro servicio depende de HttpClient. La inyección se hace de la siguiente forma:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
...
@Injectable()
export class EditorialService {
    constructor(private http: HttpClient) { }
    ...

La anotación @Injectable() indica que vamos a inyectar una dependencia. La dependencia se declara como parámetro del constructor private http: HttpClient, esto significa que dentro de la clase EditorialService podremos utilizar la variable http y a partir de ella todos los servicios que ofrece HttpClient.

Ir al inicio

HttpClient

A través de HttpClient podremos realizar get, post, put, delete y otros servicios. La signatura de get es la siguiente:

get(url: string, options?: {...}) : Observable<any>

El primer parámetro es la url para acceder a los datos. El segundo parámetro es opcional y se trata de un conjunto de opciones predefinidas para indicar la información que queremos de la respuesta.

Todas las funciones http son asíncronas, es decir se hace el llamado pero la aplicación que llamó, en este caso el front, sigue su curso. Por esta razón, estas funciones devuelven el resultado en un Observable, en un momento explicamos lo que significa, y los datos serán retornados pro defecto en formato json. El tipo any se puede remplazar por el tipo exacto de lo que estamos esperando:

@Injectable()
export class EditorialService {
    constructor(private http: HttpClient) { }
    getEditorials() : Observable<Editorial[]> {
        return this.http.get<Editorial[]>(API_URL + editorials);
    }
}

En nuestra función getEditorials() invocamos:

http.get<Editorial[]>(API_URL + editorials); sin opciones, solo la url. Esta Retorna un arreglo (Observable) de objetos conformes con la interface Editorial.

Ir al inicio

Observable

En la función estamos declarando que la función getEditorials() es Observable porque está haciendo una invocación a http.get que es una función asíncrona.

Quiere decir que la función publicará su resultado, pero está no se ejecuta hasta que un consumidor se subscribe a ella. El consumidor subscrito recibirá notificación cuando la función termine (asíncronamente).

En otras palabras, quien invoque la función, debe suscribirse a ella. En nuestro ejemplo, esto se hace en la clase del componente EditorialListComponent. Veamos el código:

...
export class EditorialListComponent implements OnInit {
    constructor(private editorialService: EditorialService) { } 
    editorials: Editorial[];
    getEditorials(): void {
        this.editorialService.getEditorials().subscribe(editorials => this.editorials = editorials);
    }
    ngOnInit() {
        this.getEditorials();
    }
}

La figura muestra los elementos que intervienen:

El atributo editorials es el que se utiliza para el despliegue en el template html. Este atributo será actualizado cuando el Observable de la función editorialService.getEditorials() le anuncie (gracias a la subscripción) a getEditorials(), de este componente, que se terminó la ejecución del get.

Este componente implementa OnInit que es una interface que define el método ngOnInit() el cual será ejecutado en creación del componente. Aquí, entonces, se llama a la función que está suscrita al servicio de traer las editoriales.

El template de la lista tiene el siguiente fragmento donde podemos ver una iteración sobre la variable editorials:

<tbody>
   <tr *ngFor = "let editorial of editorials">
        <td>{{editorial.name}}</td>
   </tr>
</tbody>

En este código, *ngFor es una directiva de angular que permite hacer un ciclo directamente sobre el html. el ciclo termina donde se cierra el elemento que tiene el atributo *ngFor. En este caso es tr. El valor de *ngFor es una expresión en typescript donde se declara la variable editorial que va a iterar sobre el arreglo editorials.

La expresión {{.. }} significa remplazar el contenido del elemento, en este caso td, con resultado de evaluar editorial.name.

Ir al inicio
⚠️ **GitHub.com Fallback** ⚠️