Tutorial Angular – 4. Mostrando una Lista

Mostrar un listado de Héroes


En esta página, ampliaremos la aplicación Tour de Héroes para que muestre un listado de héroes y permita que los usuarios seleccionen un héroe, mostrándose su detalle.

Crear héroes de prueba

Vamos a necesitar algunos héroes que mostrar.

En una versión final, los obtendremos de un servidor remoto, pero por ahora crearemos unos héroes simulados y fingiremos que provienen del servidor.

Crea un fichero llamado mock-heroes.ts en la carpeta src/app/. Define una constante HEROES como un array de diez héroes y expórtala. El fichero debería quedar así.

Mostrando los héroes

Estamos apunto de mostrar un listado de héroes en la parte superior de HeroesComponent
Abre el fichero de la clase HeroesComponent e importa el HEROES simulado.

Añade una propiedad heroes a la clase que expone estos héroes para vincularlos.

Listar héroes con *ngFor

Abre la plantilla de HeroesComponent y haz los siguientes cambios:

  • Añade un <h2> en la parte de arriba,
  • Debajo de él añade una lista HTML (<ul>)
  • Inserta un <li> dentro de <ul> que muestre la propiedad hero.
  • Añade clases CSS para los estilos (los añadiremos en el fichero CSS en breve).

Debería parecerse a esto:

Ahora cambia el <li> por esto:

El *ngFor es la directiva Angular para iterar. Repite el elemento ‘anfitrión’ por cada elemento de la lista.
En este ejemplo:

  • <li> es el elemento anfitrión
  • heroes es la lista de la clases HeroesComponent.
  • hero contiene el elemento héroe actuar para cada iteración dentro la lista.

No olvides el asterisco (*) delante de ngFor. Es una parte crítica de la sintaxis.

Después de actualizar el navegador, aparecerá el listado de héroes.

Dando estilo a los héroes

El listado de héroes debería ser atractivo y responder visualmente cuando el usuario pasa el ratón por encima y selecciona y héroe de la lista.

En el tutorial anterior, establecimos los estilos básicos para la aplicación en styles.css. La hoja de estilos no incluía estilos para el listado de héroes.
Puedes añadir más estilos en styles.css y aumentar la hoja de estilos cada vez que añades componentes.
O bien puede que prefieras definir estilos privados para cada componente y mantener todo lo que un componente necesita – código, HTML y CSS – en un solo lugar.
Este enfoque facilita la reutilización de los componentes y les proporciona un único aspecto incluso cuando los estilos globales difieren.
Puedes definir estilos privados en el array @Component.styles o como fichero(s) identificados en el array @Component.styleUrls.
Cuando el CLI generó HeroesComponent, creó una hoja de estilos heroes.component.css vacía para HeroesComponent y apuntó a ella en @Component.styleUrls de la siguiente manera:

Abre el fichero heroes.component.css y pega los estilos CSS privados para HeroesComponent. Los encontrarás en la revisión final de código al final de esta página.

Los estilos y las hojas de estilos identificados en los metadatos de @Component están limitados a ese componente en concreto. Los estilos de heroes.component.css se aplican sólo a HeroesComponent y no afecta el HTML externo o de cualquier otro componente.

Maestro/Detalle

Cuando el usuario hace clic sobre un héroe en la lista maestra, el componente debería mostrar los detalles del héroe seleccionado al final de la página

En esta sección, escucharemos el evento clic sobre un héroe y actualizaremos los detalles del héroe.

Añade un vínculo sobre el evento clic

Añade un vínculo sobre el evento clic de <li> así:

Este es un ejemplo de la sintaxis de vinculación de eventos de Angular
El paréntesis que rodea a click el indica a Angular que escuche los eventos click sobre el elemento <li>. Cuando el usuario hace clic en <li>, Angular ejecuta la expresión onSelect(hero).

OnSelect() es un método de HeroesComponent que estamos a punto de crear. Angular lo llama pasando el objeto hero que se muestra en el <li> donde has hecho clic, el mismo hero definido previamente en la expresión *ngFor.
Añade el siguiente método onSelect(), el cual asigna el héroe sobre el que hemos hecho clic en la plantilla al SelectedHero del componente.

Actualiza la plantilla de detalle

La plantilla todavía hace referencia a la antigua propiedad hero del componente, la cual ya no existe. Renombra hero a selectedHero.

Oculta el detalle vacío con *ngIf

Después de que el navegador se actualice, la aplicación deja de funcionar.

Abre el las herramientas de desarrollador del navegador y busca en la consola un mensaje de error como este:

HeroesComponent.html:3 ERROR TypeError: Cannot read property ‘name’ of undefined

Ahora haz clic en uno de los elementos del listado. La aplicación parece que funciona de nuevo. Los héroes aparecen en el listado y los detalles del héroe seleccionado aparecen en el final de la página.

¿Qué ha pasado?

Cuando la aplicación arranca, el selectedHero vale undefined (no definido) por diseño.

Las expresión de vinculación de la plantilla referidas a las propiedades de selectedHero – expresiones como {{selectedHero.name}} – fallarán porque no hay un héroe seleccionado.

La solución

El componente sólo debería mostrar los detalles del héroe seleccionado si selectedHero existe.
Envuelve el HTML de los detalles del héroe en un <div>. Añade la directiva Angular *ngIf al <div> y asígnale selectedHero.

No olvides el asterisco (*) delante de ngIf. Es una parte crítica de la sintaxis.

Después de que el navegador se actualice, el listado de nombres vuelve a aparecer. El área de detalle está vacía. Ha< clic sobre un héroe y sus detalles se mostrarán.

¿Por qué funciona?

Cuando selectedHero no está definido, ngIf elimina el detalle del héroe del DOM. No existen entonces vinculaciones de selectedHero de las que preocuparse.
Cuando el usuario selecciona un héroe, selectedHero toma un valor y ngIf pone el detalle del héroe en el DOM.

Dar estilos al héroe seleccionado

Es difícil identificar el héroe seleccionado en el listado  cuando todos los elementos li se ven igual.
Si el usuario hace clic en «Magneta», este héroe debería mostrarse con un color de fondo ligeramente diferente, tal que así:

Dar color al héroe seleccionado es tarea de la clase CSS .selected en los estilos que añadiste anteriormente. Sólo hay que aplicar la clase -selected a la etiqueta <li> cuando el usuario haga clic en ella.
La vinculación de clase de Angular facilita añadir y eliminar una clase CSS de forma condicionada. Tan sólo añade [class.some-css-class]="some-condition" al elemento al que quieras dar estilos.
Añade el siguiente vínculo [class.selected] a <li> en la plantilla de HeroesComponent.

Cuando la fila héroe actual es la misma que selectedHero, Angular le añade la clase CSS selected. Cuando los dos héroes son diferentes, Angular elimina la clase CSS.
El <li> terminado queda así:

Revisión final de código

Tu aplicación debería parecerse a este ejemplo / descarga ejemplo.
Aquí están los ficheros tratados en esta página, incluyendo los estilos de HeroesComponent.

Resumen

  • La aplicación Tour de Héroes muestra un listado de héroes en una vista Maestro/Detalle.
  • El usuario puede seleccionar un héroe y ver sus detalles.
  • Hemos usado *ngFor para mostrar una lista.
  • Hemos usado *ngIf para incluir o excluir de forma condicionada un bloque HTML.
  • Podemos activar/desactivar una clase de estilos CSS con un vínculo class.

Nota: puedes encontrar el documento original de esta entrada en https://angular.io/tutorial/toh-pt2

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *