Taller Introduccion A Angular
Taller Introduccion A Angular
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
R/
Para este aplicativo web se tendrán las siguientes consideraciones:
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
ng new nombre_proyecto
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
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
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.
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.
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.
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
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
@Component({
selector: 'app-tabla-posiciones',
templateUrl: './tabla-posiciones.component.html',
styleUrls: ['./tabla-posiciones.component.css']
})
export class TablaPosicionesComponent implements OnInit {
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;
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)
});
}
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
▪ 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
<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>
En este código:
Técnicas de Programación
Ahora bien, para poder garantizar la funcionalidad del anterior componente, se requieren
agregar los siguientes elementos:
• 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
ng g class Campeonato
ng g class Grupo
ng g class GrupoSeleccion
ng g class TablaPoscion
Técnicas de Programación
}
}
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
• 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
@Injectable({
providedIn: 'root'
})
export class CampeonatoService {
url: string;
constructor(
private http: HttpClient
) {
this.url = `${environment.urlAPI}campeonatos`;
}
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”.
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
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);
ng g s Grupo
@Injectable({
providedIn: 'root'
})
export class GrupoService {
url: string;
constructor(
private http: HttpClient
) {
this.url = `${environment.urlAPI}grupos`;
}
En este código:
▪ De manera similar al anterior servicio, se tiene una variable que almacena la URL
del controlador:
http://localhost:8080/grupos
• 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
@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
]
})
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
@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';
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:
• La lectura de un año y listar los festivos encontrados, también con base en la respuesta de la
API