0% encontró este documento útil (0 votos)
44 vistas

Taller Introduccion A Angular

Este documento presenta las técnicas para desarrollar una aplicación web en Angular que acceda a una base de datos a través de una API REST. Incluye instrucciones para instalar Angular, crear un proyecto, e implementar funcionalidades como listar campeonatos, grupos y tablas de posiciones.

Cargado por

gjcardonam
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
44 vistas

Taller Introduccion A Angular

Este documento presenta las técnicas para desarrollar una aplicación web en Angular que acceda a una base de datos a través de una API REST. Incluye instrucciones para instalar Angular, crear un proyecto, e implementar funcionalidades como listar campeonatos, grupos y tablas de posiciones.

Cargado por

gjcardonam
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 36

Técnicas de Programación

Taller 7 Fecha: Noviembre de 2023


Indicador de logro a medir: Aplicar los conceptos de la lógica de programación, de la orientación a
objetos, de la orientación a servicios y de los patrones arquitectónicos en el desarrollo de una
aplicación para Internet que acceda una base de datos relacional.

NOTAS:
• Este taller se debe hacer con carácter evaluativo (punto No 2). Representa en total una
calificación de 15%.
• Los primeros ejercicios se entregan resueltos como ejemplo para el desarrollo de los demás

1. Elaborar un aplicativo cliente Web en Angular CLI para una API RESTfull en Spring Boot que
cumple con la siguiente documentación:
Técnicas de Programación

• Un método que devuelve la lista de campeonatos FIFA que están registrados en la base
de datos
Técnicas de Programación

• Un método que, dado un campeonato, devuelve la lista de los grupos registrados

• Un método que, dado un grupo, devuelve la tabla de posiciones


Técnicas de Programación

El aplicativo web debe permitir:

• Listar los campeonatos en una lista desplegable y permitir seleccionar uno


• Cuando se seleccione un campeonato, listar los grupos del campeonato seleccionado
• Permitir seleccionar uno de los grupos listados y mostrar la respectiva tabla de posiciones

R/
Para este aplicativo web se tendrán las siguientes consideraciones:

1. Instalación del ambiente de desarrollo para implementar aplicaciones Angular

a) Cargar la consola de comandos


Técnicas de Programación

b) Verificar que esté instalado Node.JS ( es un entorno de ejecución de


JavaScript del lado del servidor que utiliza un modelo asíncrono y dirigido por eventos.
Es una Máquina Virtual muy rápida). En caso contrario, se debe descargar e instalar
primero:
node -v

c) Instalar TypeScript ( es un lenguaje de programación de código abierto que


convierte lo codificado en JavaScript, por lo que es un Superset de JavaScript)
npm install -g typescript

d) Instalar Angular CLI ( Angular CLI es una herramienta Node.JS que facilita
el inicio de proyectos y la creación del esqueleto - Scaffolding -de la mayoría de los
componentes de una aplicación Angular)
npm install -g @angular/cli
Técnicas de Programación

e) Verificar que esté instalado Angular


ng v

2. Creación de un proyecto en Angular.

a) Iniciar Visual Studio Code y con CTRL + Ñ cargar la consola de comandos

b) Crear el proyecto una vez ubicado en la carpeta de destino


Técnicas de Programación

ng new nombre_proyecto

En la ejecución de esta instrucción, es Angular CLI quien crea el siguiente Scaffolding


(andamiaje) de la aplicación (para lograr una estructura apropiada para el proyecto y
facilitar el trabajo en equipo, ya que siempre se mantiene la misma estructura):
.
├── e2e/ Elemento Descripción
├── node_modules/ editorconfig Este archivo ayuda a los
├── src/ desarrolladores a definir y
├── .editorconfig mantener estilos de codificación
├── .gitignore uniformes entre los diferentes
├── angular-cli.json editores y entornos de desarrollo.
├── package.json En caso, Angular CLI proporciona
├── tslint.json unos estilos de codificación por
├── karma.conf.js defecto para todos los
├── protractor.conf.js archivos([*]) y para los archivos
└── README.md en Markdown([*.md])

node_modules y Esta carpeta contiene todos los paquetes descargados mediante


package.json el gestor de paquetes de JavaScript, npm. Los paquetes
incluidos en esta carpeta se encuentran definidos en el archivo
package.json, dentro de dependencies y devDependencies,
acompañados de la versión del paquete instalada. En este
archivo también tenemos información general del proyecto,
como por ejemplo, los script que podemos ejecutar, el nombre
del proyecto, licencia, versión, etc
gitignore Especifica que carpetas o archivos tiene que ignorar el sistema
de control de versiones Git
README.md Contiene información básica sobre los comandos que podemos
ejecutar
karma.conf.js y Dan información a Karma y Protractor para poder ejecutar
protractor.conf.js pruebas del proyecto. La herramienta de testeo en Angular por
defecto es Jasmine. Estas herramientas permiten hacer
pruebas unitarias que son rápidas y permiten probar partes
aisladas del código, mientras que las de extremo a extremo son
lentas y comprueban el sistema entero.
tslint.json Angular CLI proporciona un linter (utilidad para reparar
automáticamente cientos de problemas), que se puede ejecutar
con el comando ng lint y que tiene su configuración en este
archivo.
Este contiene especificadas una serie de reglas para que el
código Typescript mantenga una estructura y pueda ser más
entendible y fácil de mantener
angular-cli.json Aquí se encuentra la información que Angular CLI usa para
saber por qué archivo empezar la ejecución de la aplicación,
pero también incluye información del proyecto, de las apps que
lo componen y de lo que usan esas apps para funcionar
Técnicas de Programación

Dentro de la carpeta e2e se incluye lo siguiente:


. Elemento Descripción
├── e2e/ app.po.ts y Se tiene un test básico de Angular-
├───── app.po.ts app.e2e-spec.ts CLI que comprueba que se
├───── app.e2e-spec.ts muestra correctamente la frase
└───── tsconfig.json “app works!”

tsconfig.json Indica que estamos en un proyecto Typescript y especifica las


opciones del compilador y los archivos que necesita para poder
compilar el proyecto.
Técnicas de Programación

Y finalmente, dentro de la carpeta src, la cual contiene la aplicación, se tiene:


.
├─ src/ Elemento Descripción
├──── app/ index.html Es la página HTML principal
├─────── app.component.html de la aplicación
├─────── app.component.css style.css Establece los estilos
├─────── app.component.spec.ts generales para la aplicación
├─────── app.component.ts app Carpeta que contiene el
├─────── app.module.ts código de todos los
├─────── index.ts componentes. En esta carpeta
├──── assets/ es donde Angular CLI facilita
├─────── .gitkeep el scaffolding al aportar una
├──── enviroments/ serie de comandos (ng
├─────── environments.ts generate) para la creación
├─────── environments.prod.ts automática de los
├──── favicon.ico componentes, filtros,
├──── index.html servicios, etc. que componen
├──── main.ts la aplicación y manteniendo
├──── polyfills.ts siempre la misma estructura.
├──── styles.css
├──── test.ts
├──── tsconfig.json
├──── typings.d.ts

c) Se debe abrir la carpeta generada para el proyecto para proceder a editarlo

d) Agregar al proyecto los módulos NodeJS


Técnicas de Programación

Por ejemplo, para instalar la librería Angular Material, se tendrían los siguientes
comandos:
npm install --save @angular/material @angular/cdk
ng add @angular/material

El primero instala el paquete y el segundo lo agrega al proyecto

Angular Material es una biblioteca de diseño y componentes de interfaz de usuario


desarrollada por Google para la creación de aplicaciones web y móviles con un diseño
moderno y coherente. Esta biblioteca proporciona una amplia gama de elementos
visuales y funcionalidades predefinidas, como botones, cuadros de diálogo, barras de
navegación y más, que siguen las pautas de diseño de Material Design. Angular
Material facilita la creación de aplicaciones atractivas y funcionales al ofrecer
componentes reutilizables y una apariencia consistente, lo que agiliza el proceso de
desarrollo y mejora la experiencia del usuario.

Otros módulos muy comúnmente utilizados son:


Módulo Descripción Instrucción
Bootstrap Es un framework CSS y
Javascript diseñado para npm install bootstrap
la creación de interfaces
limpias y con un diseño
responsive
Awesome FontAwesome es una npm install font-awesome
biblioteca CSS donde se
tiene una gran cantidad de
Técnicas de Programación

iconos vectoriales para


utilizar en las aplicaciones
ngx-datatable Es una biblioteca que npm i @swimlane/ngx-datatable --
ofrece una manera eficaz save --legacy-peer-deps
de presentar y administrar
datos tabulares en
aplicaciones web, con una
amplia gama de
características
personalizables, como
filtrado, clasificación,
paginación y más.
Además, es altamente
responsiva

Para agregar ngx-datatable:

Ahora, para poder editar el aplicativo, es importante conocer un poco sobre la arquitectura de
Angular y abordar introductoriamente que son los Módulos, Componentes y Servicios

Angular es una plataforma y framework utilizado para escribir aplicaciones web en


HTML y Typescript. Esta cuenta con diferentes librerías; muchas son parte del Core y son
necesarias para el funcionamiento correcto de nuestras aplicaciones, y otras son opcionales.

La creación de aplicaciones con Angular consiste básicamente en generar Plantillas


(Templates) usando HTML, los cuales se controlan con la lógica creada en los
Componentes, que serán exportados como clases. Así mismo, se agrega lógica a unos
Servicios para manejar la data que la aplicación tendrá y finalmente se encapsulan los
Componentes y Servicios en Módulos (NgModules).

La aplicación inicia su ejecución mediante el Proceso de Carga (Bootstrapping) del Módulo


Raíz (generalmente llamado "AppModule" el cual es responsable de cargar otros módulos,
componentes y servicios.). Angular toma el control y muestra contenido en el navegador,
Técnicas de Programación

reaccionando a la interacción de los usuarios que utilicen la aplicación de acuerdo a las


instrucciones que se dieron en la lógica (código).

Qué son los Módulos ?


Un NgModule declara un contexto de compilación para un conjunto de componentes. Un
NgModule puede asociar sus componentes con código relacionado, como servicios, para
formar unidades funcionales.

Cada aplicación generada con Angular cuenta con un módulo de raíz llamado
convencionalmente AppModule, el cual provee el mecanismo de arranque que inicia la
aplicación. Una aplicación generalmente contiene varios módulos funcionales.

Como en Javascript (y en muchos lenguajes con programación funcional), un módulo puede


importar funcionalidades de otros módulos, y exportar sus propias funcionalidades.

Una buena práctica es crear diferentes módulos para la aplicación y organizar el código de
manera funcional, para poder crear aplicaciones bien estructuradas cuando son complejas y
escalables. Además, de esta forma se puede sacar provecho de la Carga Diferida (Lazy
Loading, el cual es un patrón de diseño que consiste en retrasar la carga o inicialización de
un objeto hasta el mismo momento de su utilización) y así mejorar el rendimiento de la
aplicación.

Qué son los Componentes ?


Cada aplicación de Angular tiene al menos un componente. Al igual que el módulo de raíz,
existe el Componente Raíz (Root Component). que conecta una jerarquía de componentes
con el DOM (Document Object Model, el cual es una interfaz que proporciona un conjunto
estándar de objetos para representar documentos HTML, XHTML y XML). Cada componente
define una clase que contiene data y lógica, y está vinculada a la plantilla HTML.

Que son los Templates ?


Técnicas de Programación

Una Plantilla (Template) es una mezcla de HTML con Angular markup (tags personalizados
de Angular). Las directivas de un Template proveen lógica de programación, y hacen data
binding (enlace a los data de la aplicación) con las vistas.

Hay dos tipos de data binding:


• Event binding o enlace de eventos, que responden a la interacción del usuario al
modificar algún input en la aplicación, actualizando la data.
• Property binding o enlace de propiedades, que permite agregar valores modificados
desde la data al HTML

Qué son Servicios e Inyección de Dependencias ?


Toda la data o lógica que no está asociada directamente a una vista y que se quiere utilizar en
diferentes partes de la aplicación y entre diferentes componentes, puede ser escrita en un
Servicio. Tal como un componente, los servicios son exportados como clases. Los servicios
cuentan con el decorator @Injectable() que provee metadata que permite que los servicios
sean inyectados en componentes como dependencias.

Las Inyección de Dependencias (Dependency injection) permite manejar las clases de los
componentes de forma ligera y eficiente. No obtienen datos del servidor, validan los user input
o logs directamente en la consola; delegan la obtención de datos a los servicios.

Estos fueron algunos conceptos básicos sobre los principales bloques de arquitectura de una
aplicación en Angular. El siguiente diagrama muestra cómo se relacionan estas piezas
básicas:
Técnicas de Programación

• Con lo anterior en mente, se comenzará el desarrollo agregando un componente que


incluirá la interfaz de usuario y la funcionalidad requerida para cumplir el requerimiento:

Para ello se agregará una carpeta al proyecto (como subcarpeta de la carpeta app)
denominada “componentes” y luego se ejecutará el comando de creación de
componentes (ng generate component)

ng g c TablaPosiciones

El resultado es que se agrega al proyecto los


archivos:
• tabla-posiciones.component.html que
contendrá el HTML para la interfaz de
usuario
• tabla-posiciones.component.ts que contendrá
el código TypeScript que desarrollará la
funcionalidad del componente

El código TypeScript de este componente sería:


import { Component, OnInit } from '@angular/core';
import { Campeonato } from 'src/app/entidades/campeonato';
Técnicas de Programación

import { ColumnMode, SelectionType } from '@swimlane/ngx-datatable';


import { TablaPosicion } from 'src/app/entidades/tabla-posicion';
import { CampeonatoService } from 'src/app/servicios/campeonato.service';
import { Grupo } from 'src/app/entidades/grupo';
import { GrupoService } from 'src/app/servicios/grupo.service';

@Component({
selector: 'app-tabla-posiciones',
templateUrl: './tabla-posiciones.component.html',
styleUrls: ['./tabla-posiciones.component.css']
})
export class TablaPosicionesComponent implements OnInit {

public idCampeonato: number = 0;


public campeonatos: Campeonato[] = [];
public idGrupo: number = 0;
public grupos: Grupo[] = [];

public columnas = [
{ name: 'Seleccion', prop: 'pais', width: 300 },
{ name: 'PJ', prop: 'pJ', width: 50 },
{ name: 'PG', prop: 'pG', width: 50 },
{ name: 'PE', prop: 'pE', width: 50 },
{ name: 'PP', prop: 'pP', width: 50 },
{ name: 'GF', prop: 'gF', width: 50 },
{ name: 'GC', prop: 'gC', width: 50 },
{ name: 'Puntos', prop: 'puntos', width: 50 },
];
public posiciones: TablaPosicion[] = [];
public modoColumna = ColumnMode;
public tipoSeleccion = SelectionType;
public posicionSeleccionada: TablaPosicion | undefined;

constructor(private campeonatoService: CampeonatoService,


private grupoService: GrupoService,
) {
}

ngOnInit(): void {
this.listarCampeonatos();
}

public listarCampeonatos() {
this.campeonatoService.listar()
.subscribe(data => {
this.campeonatos = data;
},
err => {
window.alert(err.message)
});
}

public seleccionarCampeonato() {
this.campeonatoService.listarGrupos(this.idCampeonato)
.subscribe(data => {
this.grupos = data;
Técnicas de Programación
},
err => {
window.alert(err.message)
});
}

public seleccionarGrupo() {
this.grupoService.obtenerTablaPosiciones(this.idGrupo)
.subscribe(data => {
this.posiciones = data;
},
err => {
window.alert(err.message)
});
}

public onActivate(event: any) {


if (event.type == 'click') {
this.posicionSeleccionada = event.row;
}
}

En este código:
▪ Se declaran las variables idCampeonato e idGrupo mediante las cuales se
seleccionan el campeonato y el grupo para la consulta respectiva
▪ Se declara un arreglo de objetos Campeonato (denominado campeonatos) que se
llenará con la consulta a la API mediante el servicio respectivo (objeto de la clase
CampeonatoService) y que servirá de fuente de datos para la lista desplegable
respectiva
▪ Se declara un arreglo de objetos Grupo que se llenará con la consulta a la API
mediante el servicio respectivo (objeto de la clase GrupoService) y que servirá de
fuente de datos para la lista desplegable respectiva
▪ Se declara un arreglo de objetos que definen los atributos de las columnas de la
rejilla de datos donde se desplegará la tabla de posiciones consultada:
➢ name: atributo con el título del encabezado
➢ prop: atributo con el nombre del campo que se desplegará
➢ width: atributo con el ancho de la columna
▪ Se declara un arreglo de objetos TablaPosicion que se llenará con la consulta a la
API mediante el servicio GrupoService y que servirá de fuente para la rejilla de
datos respectiva
▪ Se declara un objeto de la clase TablaPosicion denominado posicionSeleccionada
el cual corresponde a la fila que se seleccione en la rejilla de datos
▪ Se declara un objeto de la clase ColumnMode que se utiliza para especificar el
modo de las columnas en una tabla de datos. Estos modos pueden ser
➢ Standard: Este es el modo predeterminado. Las columnas se ajustarán
automáticamente según el contenido, pero si el contenido es demasiado
ancho para la columna, se cortará y no se mostrará completo.
➢ Flex: En este modo, las columnas se expandirán y contraerán
automáticamente para ajustarse al espacio disponible. Esto permite que las
columnas se ajusten dinámicamente al tamaño del contenedor de la tabla.
➢ Force: En este modo, las columnas se ajustarán automáticamente según el
contenido, pero si el contenido es demasiado ancho, las columnas se
Técnicas de Programación

reducirán para adaptarse al espacio disponible. Esto puede resultar en que


el contenido se reduzca o abrevie.
➢ ForceFit: Similar al modo Force, pero las columnas se ajustarán para
asegurarse de que todas las columnas se ajusten en el espacio disponible,
sin reducir el contenido.
➢ Fixed: En este modo, las columnas tendrán un ancho fijo que se establece
manualmente y no cambiará según el contenido. Esto significa que no se
ajustarán automáticamente para adaptarse al contenido
▪ Se declara un objeto de la clase SelectionType que se utiliza para definir el tipo de
selección que se aplicará a las filas de una tabla de datos. Los tipos de selección
disponibles son:
➢ Single: En este modo, solo se permite seleccionar una sola fila a la vez. Si
se selecciona una fila diferente, la selección previa se deselecciona
automáticamente. Este modo es útil cuando se necesita seleccionar una
fila específica de la tabla.
➢ Multi: En este modo, se permite la selección de múltiples filas de la tabla
de datos al mismo tiempo. Los usuarios pueden seleccionar varias filas sin
deseleccionar las filas previamente seleccionadas. Esto es útil cuando se
necesita realizar acciones en varias filas a la vez, como eliminar o editar
múltiples elementos.
➢ MultiClick: Similar al modo Multi, pero las filas se seleccionan o
deseleccionan haciendo clic en ellas en lugar de usar casillas de
verificación de selección. Esto permite una selección más intuitiva haciendo
clic directamente en las filas.
➢ Checkbox: En este modo, las filas se seleccionan utilizando casillas de
verificación en lugar de seleccionar toda la fila. Esto es útil cuando se
desea una interfaz de usuario que permita a los usuarios seleccionar filas
mediante casillas de verificación Standard
▪ Para los objetos que representan los servicios (campeonatoService y
grupoService) se utiliza la inyección de dependencias. Angular utiliza un sistema
de inyección de dependencias para proporcionar instancias de objetos o servicios
a las clases que los necesitan. En lugar de que las clases creen sus propias
instancias de objetos, Angular se encarga de proporcionar esas instancias de
manera eficiente y coherente. Se utiliza principalmente en componentes y
servicios. Generalmente se inyectan dependencias en el constructor de un
componente o servicio
▪ La clase correspondiente a este componente implementa la interfaz OnInit. Esta es
parte del ciclo de vida de un componente en Angular y se utiliza para definir un
método que se ejecutará cuando se inicialice el componente. En este caso se
llamará al método listarCampeonatos()
▪ El método listarCampeonatos() se subscribe al método listar() del servicio de
Campeonato. Suscribirse a un método generalmente significa observar un flujo de
datos emitido por una función o método asincrónico. Esto se hace comúnmente
utilizando observables. Y es que, en este caso, el método listar() del servicio
devuelve un Observable al consumir asincrónicamente un método de la API. Al
suscribirse a un observable, generalmente se proporcionan dos funciones de
devolución de llamada: una para manejar los datos emitidos por el observable y
otra para manejar errores en caso de que ocurran.
En la primera función, se asigna la información de la respuesta de la API al arreglo
de objetos de la clase Campeonato y en la segunda se muestra el mensaje de
error recibido
Técnicas de Programación

▪ Adscrito al evento click de las opciones de la lista desplegable que muestra los
campeonatos se tiene el método seleccionarCampeonato() el cual también se
suscribe a un método que devuelve un Observable. En este caso al método
listarGrupos() del servicio de Campeonato, y en el caso de la primera función, se
asigna la respuesta al arreglo de objetos de la clase Grupo.
Se debe observar que este método requiere el parámetro idCampeonato el cual se
obtiene de la lista desplegable
▪ Adscrito al evento click de las opciones de la lista desplegable que muestra los
grupos de un campeonato, se tiene el método seleccionarGrupo() el cual también
se suscribe a un método que devuelve un Observable. En este caso al método
obtenerTablaPosiciones() del servicio de Grupo, y en el caso de la primera
función, se asigna la respuesta al arreglo de objetos de la clase TablaPosiciones.
▪ Por último, se tiene un método que responde a un evento de la rejilla de datos. El
evento activate en el componente ngx-datatable se utiliza para capturar la
activación de una fila en la rejilla de datos. Esto puede ocurrir cuando un usuario
hace clic en una fila específica. El evento activate proporciona información sobre la
fila activada, como los datos de la fila y la fila misma.
En este caso, se valida que el tipo de evento sea un click, en cuyo caso se asigna
la fila seleccionada un objeto de la clase TablaPosicion

Y el código HTML de este componente sería:


<mat-toolbar class="mat-primary mat-toolbar-single-row mat-elevatmat-z8
color-barra" color="background">
<img src="../assets/imagenes/Logo FIFA.jpg" height="80px">
<div class="center">
Campeonatos FIFA
</div>
</mat-toolbar>

<mat-form-field appearance="fill">
<mat-label>Campeonato</mat-label>
<mat-select [(value)]="idCampeonato">
<mat-option *ngFor="let c of campeonatos" [value]="c.id"
(click)="seleccionarCampeonato()">
{{c.nombre}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Grupo</mat-label>
<mat-select [(value)]="idGrupo">
<mat-option *ngFor="let g of grupos" [value]="g.id"
(click)="seleccionarGrupo()">
{{g.nombre}}
</mat-option>
</mat-select>
</mat-form-field>

<ngx-datatable class="dark" [headerHeight]="50" [footerHeight]="50"


[rowHeight]="20" [rows]="posiciones"
[columns]="columnas" [columnMode]="modoColumna.force" [limit]="10"
[selectionType]="tipoSeleccion.single"
(activate)="onActivate($event)" [rowHeight]="'auto'">

</ngx-datatable>
En este código:
Técnicas de Programación

• Se tiene inicialmente un componente mat-toolbar el cual es un componente de la


librería Angular Material que se utiliza para crear barras de herramientas (toolbars)
en aplicaciones web desarrolladas con Angular. Las barras de herramientas son
áreas de la interfaz de usuario que suelen contener botones, enlaces, títulos y
otros elementos de navegación o de acción.
En este caso, se utiliza para mostrar el logo de la FIFA y un título para la página
• El componente mat-form-field es otro componente de la librería Angular Material
que se utiliza para crear formularios en aplicaciones web desarrolladas con
Angular. Proporciona un contenedor flexible para los elementos de entrada de un
formulario, como campos de texto, selectores, casillas de verificación, etc.
Una característica común de mat-form-field es la capacidad de mostrar etiquetas
flotantes. Cuando un usuario coloca el cursor en un campo de entrada, la etiqueta
se eleva para proporcionar información sobre el tipo de entrada esperado.
En este caso para el primer mat-form-field se coloca dentro una etiqueta
(componente mat-label) que indica que se está leyendo el campeonato, y un
componente mat-select

• El componente mat-select es parte de la librería Angular Material y se utiliza para


crear listas desplegables (selects) en aplicaciones web desarrolladas con Angular.
Una lista desplegable es un elemento de formulario que permite a los usuarios
seleccionar una opción de una lista predefinida. Entre las características de este
componente, permite al usuario seleccionar una opción de una lista de elementos
que se puede cargar dinámicamente desde una fuente de datos.
En este ejercicio, se utiliza mat-select para crear una lista desplegable de
campeonatos. Las opciones se generan dinámicamente utilizando *ngFor para
iterar sobre el arreglo campeonatos. La propiedad [(value)] se utiliza para vincular
la selección del usuario al modelo de datos en el componente. En este caso a la
variable idCampeonato.
Cada opción es definida por un componente mat-option y está asociada a un
valor específico utilizando la propiedad [value]. Esto permite vincular la selección
del usuario con un valor específico en el componente de Angular.
• De manera similar, se tiene otra lista desplegable para listar los grupos del
campeonato seleccionado y esta se llena iterando el arreglo grupos
• Finalmente se tiene un componente ngx-datatable correspondiente a la rejilla de
datos los cuales tienen los siguientes atributos:
➢ [rows]: Esta propiedad se utiliza para especificar los datos que se
mostrarán en la tabla. Debe asignarse a un arreglo de objetos que
representan las filas de datos, en este caso el arreglo posiciones
➢ [columns]: Se utiliza para definir las columnas de la tabla. Debes asignar
un arreglo de objetos de columna que describen las características de cada
Técnicas de Programación

columna, como el título y el nombre de la propiedad de datos que se


mostrará. En este caso el arreglo columnas
➢ [columnMode]: Permite especificar el modo de las columnas. Los valores
comunes incluyen 'standard', 'flex', 'force', 'force-fill' y 'fixed'. Controla cómo
se ajustan las columnas en la tabla.
➢ [headerHeight]: Define la altura de la fila de encabezado.
➢ [footerHeight]: Define la altura de la fila de pie de página.
➢ [rowHeight]: Establece la altura de las filas de datos.
➢ [scrollbarV]: Indica si se debe mostrar una barra de desplazamiento
vertical.
➢ [scrollbarH]: Indica si se debe mostrar una barra de desplazamiento
horizontal.
➢ [virtualization]: Habilita o deshabilita la virtualización de filas para un
rendimiento mejorado en tablas largas.
➢ [selectionType]: Define el tipo de selección que se utilizará en la tabla.
Puede ser 'single', 'multi', 'multiClick', o 'checkbox'.
➢ [selected]: Un arreglo de objetos que representa las filas seleccionadas en
la tabla.
➢ (activate): Se utiliza para capturar el evento de activación de una fila en la
tabla.
➢ (select): Permite manejar eventos cuando se selecciona una fila.
➢ (deselect): Permite manejar eventos cuando se deselecciona una fila.

Ahora bien, para poder garantizar la funcionalidad del anterior componente, se requieren
agregar los siguientes elementos:

Elemento Archivos Descripción


Clase Campeonato • campeonato.ts Define la entidad respectiva. Las entidades
representan la información a procesar. En
este caso, la procedente de la API a través de
los servicios
Clase Seleccion • seleccion.ts Define la entidad respectiva
Clase Grupo • grupo.ts Define la entidad respectiva
Clase • grupo-selección.ts Define la entidad respectiva
GrupoSelección
Clase • tabla-posicion.ts Define la entidad respectiva
TablaPosiciones
Servicio • campeonato.sevice.ts Define la funcionalidad que accede a la API a
Campeonato través del controlador de Campeonatos
Servicio Grupo • grupo.sevice.ts Define la funcionalidad que accede a la API a
través del controlador de Grupos
Técnicas de Programación

Modulo • referencias- Organiza funcionalidades relacionadas con la


ReferenciasMaterial material.module.ts librería Material

• Para ello se agregará otra carpeta al proyecto (también como subcarpeta de la carpeta
app) denominada “entidades” y luego se ejecutará el comando de creación de clases (ng
generate class)

ng g class Seleccion

El resultado es que se agrega al proyecto el archivo:


• seleccion.ts que contendrá el código TypeScript
en el que se definirá la estructura de la clase

El código TypeScript de esta clase sería:


export class Seleccion {
constructor(
public id: number,
public nombre: string,
public entidad: string,
) {
}
}
Donde se definen los atributos de la clase Selección en el método constructor.

• En la misma carpeta se agregarán las demás clases:

ng g class Campeonato
ng g class Grupo
ng g class GrupoSeleccion
ng g class TablaPoscion
Técnicas de Programación

El resultado es que se agregan al proyecto los archivos:


• campeonato.ts que contendrá el código
TypeScript en el que se definirá la estructura de la
clase Campeonato
• grupo.ts que contendrá el código TypeScript en el
que se definirá la estructura de la clase Grupo
• grupo-seleccion.ts que contendrá el código
TypeScript en el que se definirá la estructura de la
clase GrupoSeleccion
• tabla-posicion.ts que contendrá el código
TypeScript en el que se definirá la estructura de la
clase TablaPosicion

El código TypeScript del archivo campeonato.ts sería:


import { Seleccion } from "./seleccion";

export class Campeonato {


constructor(public id: number,
public nombre: string,
public pais: Seleccion,
public año: number
) {

}
}
Donde se definen los atributos de la clase Campeonato en el método constructor.
Obsérvese la referencia a la clase Seleccion
Técnicas de Programación

El código TypeScript del archivo grupo.ts sería:


export class Grupo {
constructor(
public id: number,
public nombre: string,
) {
}
}
Donde se definen los atributos de la clase Grupo en el método constructor.

El código TypeScript del archivo grupo-seleccion.ts sería:


import { Grupo } from "./grupo";
import { Seleccion } from "./seleccion";

export class GrupoSeleccion {


constructor(public grupo: Grupo,
public pais: Seleccion,
) {
}
}
Donde se definen los atributos de la clase GrupoSeleccion en el método constructor.
Obsérvese las referencias a las clases Selección y Grupo.

Por último, el código TypeScript del archivo tabla-posicion.ts sería:


export class TablaPosicion {
constructor(
public id: number,
public pais: string,
public pJ: number,
public pG: number,
public pE: number,
public pP: number,
public gF: number,
public gC: number,
public puntos: number,
) {
}
}
Donde se definen los atributos de la clase TablaPosicion en el método constructor.

• Ahora se agregará otra carpeta al proyecto (también como subcarpeta de la carpeta app)
denominada “servicios” y luego se ejecutará el comando de creación de servicios (ng
generate service)

ng g s Campeonato
Técnicas de Programación

El resultado es que se agrega al proyecto el archivo:


• campeonato.services.ts que contendrá el código
TypeScript en el que se implementarán las
solicitudes al controlador Campeonato de la API

El código TypeScript de esta clase sería:


import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { environment } from "src/environments/environment";
import { Campeonato } from "../entidades/campeonato";
import { Grupo } from "../entidades/grupo";

@Injectable({
providedIn: 'root'
})
export class CampeonatoService {

url: string;

constructor(
private http: HttpClient
) {
this.url = `${environment.urlAPI}campeonatos`;
}

public listar(): Observable<Campeonato[]> {


let urlT = `${this.url}/listar`;
return this.http.get<Campeonato[]>(urlT);
}

public listarGrupos(id: number): Observable<Grupo[]> {


let urlT = `${this.url}/grupos/${id}`;
return this.http.get<Grupo[]>(urlT);
}

En este código:
Técnicas de Programación

▪ Se declara una variable de clase que almacena la URL del controlador. Esta se
inicializa en el método constructor, concatenando la variable de entorno urlAPI
(proveniente del archivo environment.ts) con la palabra “campeonatos”.

El archivo environment.ts es un archivo de configuración utilizado para definir


variables de entorno y configuraciones específicas de un entorno de desarrollo.
Este archivo se encuentra en la carpeta src/environments de todo proyecto
Angular y se utiliza para proporcionar valores que pueden variar entre entornos,
como el entorno de desarrollo y el entorno de producción. Esto es particularmente
útil para separar configuraciones que difieren entre entornos, como las URL de las
API, las claves de acceso a servicios externos u otras variables de configuración.

En un proyecto Angular, predeterminadamente, se proporcionan dos archivos


environment:

➢ environment.ts: Él cual se utiliza para configuraciones específicas del


entorno de desarrollo como por ejemplo variables correspondientes a las
URL de APIs de prueba
➢ environment.prod.ts: Este archivo se utiliza para configuraciones
específicas del entorno de producción. Por ejemplo, la URL de producción
de una API.

En este ejercicio, se tendrá el siguiente código para el archivo environment.ts:


export const environment = {
production: false,
urlAPI: "http://localhost:8080/",
};
En el que se puede observar la declaración la variable de entorno urlAPI
almacenando la URL de la API que va a ser utilizada.

Para acceder a las variables de entorno en una aplicación Angular, se debe


importar el objeto environment y usar sus propiedades en el código, como en este
caso para completar la URL de la API
import { environment } from "src/environments/environment";

Técnicas de Programación
this.url = `${environment.urlAPI}campeonatos`

▪ El método listar() es un método con características muy especiales. En primer


lugar, el tipo de dato de salida tiene la notación Observable<>.

La notación Observable<> en Angular se refiere a la clase Observable


proporcionada por la librería RxJS (sigla de Reactive Extensions for JavaScript en
inglés). RxJS es ampliamente utilizado para manejar flujos de datos asincrónicos,
como respuestas de API, eventos del usuario y otros tipos de datos que llegan con
el tiempo. El Observable es una parte fundamental de la programación reactiva en
Angular.

Un Observable es una secuencia de eventos que pueden incluir valores, errores o


notificaciones de completitud. Algunas de las operaciones y características
comunes incluyen:
➢ Suscripción: se suscribe a un Observable para escuchar y reaccionar a
los eventos emitidos por él
➢ Operadores: sirven para transformar, filtrar, mapear o combinar los datos
en el flujo
➢ Manejo de Errores: se pueden manejar errores que se produzcan en el
flujo de datos utilizando operadores como catchError o retry
➢ Composición: Se Pueden combinar múltiples Observables en uno solo
utilizando operadores como merge, concat, forkJoin, etc
➢ Unsubscribing: Es importante desuscribirse de los Observable cuando ya
no se necesite escuchar los datos para evitar pérdidas de memoria. Se
Puedes hacer llamando al método unsubscribe() en el objeto de
suscripción

Dentro del cuerpo del método listar(), la primera instrucción es una concatenación
que completa el endpoint del método de la api a consumirse. En este caso la URL
completa sería:
http://localhost:8080/campeonatos/listar

Resultado de concatenar la URL del controlador (que a su vez resulta de la


concatenación del servidor de API con el nombre del controlador) con el nombre
del método.

Seguido, Se hace uso del método genérico de la clase HttpClient, get<T> el cual
representa una solicitud HTTP GET a un servidor con el tipo genérico <T>. Por
ejemplo, la instrucción en cuestión:
return this.http.get<Campeonato[]>(urlT);

Significa que se está haciendo un llamado al endpoint cuyo método esté


direccionado mediante la URL almacenada en la variable ulrT en una solicitud de
tipo GET que debe devolver un arreglo de objetos Campeonato

La clase HttpClient en Angular es un módulo que proporciona una forma


simplificada y basada en observables para realizar peticiones HTTP a servidores
remotos. Permite a los desarrolladores realizar solicitudes HTTP, como GET,
POST, PUT, DELETE, etc., gestionar las respuestas, y trabajar con datos JSON u
Técnicas de Programación

otros formatos de datos de manera eficiente y asincrónica, lo que facilita la


comunicación con servicios web y la obtención de datos en aplicaciones Angular.

▪ El método listarGrupos(), de manera similar al anterior método, realiza una


solicitud GET en este caso al endpoint:
http://localhost:8080/campeonatos/grupos/{id}

el cual pasa en la URL un parámetro de entrada que corresponde a la clave


primaria del Campeonato del que se desea consultar la lista de grupos registrados
y los cuales son retornados también a través de un Observable

• Ahora se ejecutará de nuevo el comando de creación de servicios para la información


asociada a los Grupos

ng g s Grupo

El resultado es que se agrega al proyecto el archivo:


• grupo.services.ts que contendrá el código
TypeScript en el que se implementarán las
solicitudes al controlador Grupo de la API

El código TypeScript de esta clase sería:


import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { environment } from "src/environments/environment";
Técnicas de Programación
import { TablaPosicion } from "../entidades/tabla-posicion";

@Injectable({
providedIn: 'root'
})
export class GrupoService {

url: string;

constructor(
private http: HttpClient
) {
this.url = `${environment.urlAPI}grupos`;
}

public obtenerTablaPosiciones(id: number):


Observable<TablaPosicion[]> {
let urlT = `${this.url}/posiciones/${id}`;
return this.http.get<TablaPosicion[]>(urlT);
}

En este código:
▪ De manera similar al anterior servicio, se tiene una variable que almacena la URL
del controlador:
http://localhost:8080/grupos

▪ El método obtenerTablaPosiciones(), de manera similar a los del anterior servicio,


realiza una solicitud GET al endpoint:
http://localhost:8080/grupos/posiciones/{id}

el cual pasa en la URL un parámetro de entrada que corresponde a la clave


primaria del Grupo del que se desea consultar la tabla de posiciones la cual es
retornada a través de un Observable

• Para poder acceder a todas las funcionalidades que ofrece la librería Material, o más
específicamente a las requeridas por el proyecto (como label, input, select, entre otros),
se va a agregar un módulo que las deje disponibles. Para ello se ejecutará el comando de
creación de módulos (ng generate module)

ng g m ReferenciasMaterial
Técnicas de Programación

El resultado es que se agrega al proyecto el archivo:


• referencias-material.module.ts que contendrá el
código TypeScript en el que se exportarán todas
las referencias a los elementos más utilizados de
la librería Material

El código TypeScript de esta clase sería:


import { NgModule } from '@angular/core';

import { MatToolbarModule } from '@angular/material/toolbar';


import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatIconModule } from '@angular/material/icon';
import { BrowserAnimationsModule } from '@angular/platform-
browser/animations';
import { MatListModule } from '@angular/material/list';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatRadioModule } from '@angular/material/radio';
import { MatTabsModule } from '@angular/material/tabs';
import { MatDialogModule } from '@angular/material/dialog';
import { MatDividerModule } from '@angular/material/divider';
import { MatSelectModule } from '@angular/material/select';

import { MatCheckboxModule } from '@angular/material/checkbox';

import { MatDatepickerModule } from '@angular/material/datepicker';


import { MatNativeDateModule } from '@angular/material/core';

import { MatAutocompleteModule } from '@angular/material/autocomplete';

import { MatMenuModule } from '@angular/material/menu';

import { MatProgressSpinnerModule } from '@angular/material/progress-


spinner';
import { CommonModule } from '@angular/common';

@NgModule({
exports: [
MatToolbarModule,
MatCardModule,
Técnicas de Programación
MatFormFieldModule,
MatInputModule,
MatButtonModule,
MatSidenavModule,
MatIconModule,
BrowserAnimationsModule,
MatListModule,
MatExpansionModule,
MatRadioModule,
MatTabsModule,
MatDialogModule,
MatDividerModule,
MatMenuModule,
MatSelectModule,
MatCheckboxModule,

MatNativeDateModule,
MatDatepickerModule,
MatAutocompleteModule,

MatProgressSpinnerModule
]
})

export class ReferenciasMaterialModule { }

Un módulo en Angular se define mediante la decoración @NgModule. En este caso se


utiliza la instrucción exports para especificar qué componentes quedarán disponibles
para otros módulos o componentes fuera del módulo actual. Esto significa que los
elementos marcados como "exportados" en este módulo pueden ser utilizados por otros
módulos de la aplicación.

• Ahora se agregará una carpeta denominada “imágenes” dentro de la carpeta ”assets”


Técnicas de Programación

La carpeta ”assets” es el lugar donde se almacenan archivos estáticos que se deben


incluir en la aplicación, como imágenes, fuentes, archivos de configuración, documentos y
otros recursos no relacionados con el código fuente de la aplicación. Estos archivos son
copiados tal cual, a la carpeta de salida de la aplicación durante el proceso de
construcción, lo que los hace accesibles a través de la URL de la aplicación.

La estructura de archivos dentro de la carpeta "assets" se mantendrá en la carpeta de


salida, lo que significa que, si se tienen archivos en subdirectorios dentro de ella, podrán
ser accedidos utilizando las rutas correspondientes en la aplicación Angular.

Dentro de la carpeta “imágenes” se copiará el archivo con el logo de la FIFA para


ambientar la aplicación, el cual es accedido desde el componente TablaPosiciones

• Para culminar la edición del aplicativo, se editarán los archivos app.component.html,


app.module.ts y styles.css.

El archivo app.component.html es el punto de entrada visual de la aplicación y en este


caso contendrá una referencia al componente TablaPosiciones. El tag a utilizar es el que
se definió en el atributo selector de la decoración @Component de este componente:
@Component({
selector: 'app-tabla-posiciones',
templateUrl: './tabla-posiciones.component.html',
styleUrls: ['./tabla-posiciones.component.css']
})

El código HTML de este componente sería:


<app-tabla-posiciones></app-tabla-posiciones>
Técnicas de Programación

En Angular, el archivo app.module.ts es una parte clave que define y configura el módulo
principal de la aplicación. Este módulo principal suele llamarse AppModule y desempeña
varios roles importantes:
▪ Contiene la decoración @NgModule que especifica los metadatos esenciales,
como los componentes, directivas, pipes y servicios que pertenecen a este
módulo. Además, incluye configuraciones importantes, como las rutas y otros
módulos que el módulo principal importa
▪ También especifica el componente principal que se utilizará como punto de
entrada para la aplicación mediante la propiedad Bootstrap
▪ A través de la propiedad imports, importa otros módulos necesarios para la
aplicación, como BrowserModule, el cual proporciona funcionalidades esenciales
para aplicaciones web
▪ En la propiedad declarations, se incluyen los componentes, directivas y pipes que
pertenecen a este módulo. Esto permite a Angular reconocer y utilizar estos
elementos en la aplicación

El código TypeScript de esta clase sería:


import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';


import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-
browser/animations';
import { TablaPosicionesComponent } from './componentes/tabla-
posiciones/tabla-posiciones.component';
import { ReferenciasMaterialModule } from './referencias-
material/referencias-material.module';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';

@NgModule({
declarations: [
AppComponent,
TablaPosicionesComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
ReferenciasMaterialModule,
NgxDatatableModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

El archivo styles.css es un archivo de estilo global en una aplicación Angular. Este archivo
es utilizado para definir estilos que se aplicarán a toda la aplicación y afectarán a todos
los componentes y elementos en ella. Es el lugar común para definir reglas de estilo que
se aplican de manera global en toda la aplicación Angular.

En este proyecto, se importarán estilos provistos por las librerías Material y ngx-datatable
para disponer temáticas en los elementos visuales a utilizar:
Técnicas de Programación
/* You can add global styles to this file, and also import other style
files */

@import "~@angular/material/prebuilt-themes/indigo-pink.css";

@import '../node_modules/@swimlane/ngx-datatable/themes/material.css';
@import '../node_modules/@swimlane/ngx-datatable/themes/dark.css';
@import '../node_modules/@swimlane/ngx-datatable/themes/bootstrap.css';

html, body { height: 100%; }


body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }

Con todo lo anterior implementado, se puede proceder a la ejecución del aplicativo mediante
el comando:
ng serve --open

Esto activará la compilación del proyecto completo y la respectiva generación del ejecutable
que luego será desplegado en el navegador de internet
Técnicas de Programación

2. Elaborar un aplicativo cliente Web en Angular CLI para una API RESTfull en Spring Boot que cumple
con la siguiente documentación:

Un primer método que verifica si una fecha corresponde a un festivo


Técnicas de Programación

Y un segundo método que devuelve la lista de festivos de un año.


Técnicas de Programación

El aplicativo web debe permitir:


• La lectura de una fecha y mostrar si es festivo o no con base en la respuesta de la API

• La lectura de un año y listar los festivos encontrados, también con base en la respuesta de la
API

El aplicativo debe incluir:


• El servicio que se conecte a la API
• Las entidades para recibir los datos
• Uso de librerías de diseño como Material y ngx-datatable

También podría gustarte