Guía Aplicación Angular
Guía Aplicación Angular
La siguiente guía explica los pasos a seguir para crear una aplicación con Angular que consuma el API de
videojuegos, lea con detenimiento, analizando y comprendiendo cada uno de los aspectos que se exponenen.
TABLA DE CONTENIDO
1
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
ACTUZALIZAR ANGULAR CLI VERSION 8
La aplicaciones de Angular que se desarrolla en el curso la versión 8, para poder crear proyectos utilizando la
última versión es necesario que actualice Angular CLI, con el siguiente comando
ng new nombreAplicacion
INSTALAR LIBRERÍAS
Para transportar un proyecto de angular y disminuir su peso, se puede eliminar la carpeta “node_modules”,
que contiene las librerías que se utilizan en el proyecto, las cuales están definidas en el archivo
“package.json”. Para instalar o reestablecerlas se utiliza el siguiente comando
npm install
Para poder instalar cualquier librería que se quiera utilizar en el proyecto, es necesario conocer el nombre con
el que se puede llamar la dependencia para su respectiva instalación. Por ejemplo:
En el archivo “angular.json” sirve de guía para Angular CLI, declarando una serie de atributos que permiten a
esta herramienta realizar operaciones la aplicación. Los parámetro dentro la sección “build”, definen las
características de construcción de la aplicación, aquí se definen los estilos y scripts necesarios, y demás
aspectos que se pueden visualizar en este archivo.
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/appVJ8",
"index": "src/index.html",
"main": "src/main.ts",
2
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": false,
"assets": ["src/favicon.ico", "src/assets"],
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/@fortawesome/fontawesome-free/css/all.css",
"src/styles.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js",
"node_modules/@fortawesome/fontawesome-free/js/all.js"
]
}
…
CREAR MÓDULOS
•crear
ng g o ng generate
•crear un modulo
m o module
CREAR COMPONENTES
Cada uno de los siguientes componentes están precedidos por el nombre de la carpeta del nombre del
módulo al que pertenecen
3
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
ng generate component core/header
ng generate component core/footer
ng generate component core/banner
ng generate component core/page-not-found
ng generate component home/acercade
ng generate component home/inicio
ng generate component videojuego/videojuego-index
ng generate component videojuego/videojuego-show
A cada uno de estos componentes debe definirle el HTML que se encuentra en los recursos del curso.
PÁGINA INICIAL
El app.component es el que está definido por defecto para cargarse inicialmente, en este componente se
llaman los demás componentes que forman la página inicial.
Es necesario hacer visible el componentes header, footer, banner e inicio, ya que no están asociados a una
ruta, para lograr esto es necesario especificar en el modulo que pertenecen que se pueden exportar. Por
ejemplo:
home.module.ts
@NgModule({
declarations: [AcercadeComponent, InicioComponent],
imports: [CommonModule, HomeRoutingModule],
exports: [InicioComponent]
})
export class HomeModule {}
Especifique esta mismo características para los componentes que se le indica.
Además que tiene que los modelos a que pertenecen estos componentes deben estar importados el modelo
principal app.module.
4
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
PÁGINA INICIAL
<app-header></app-header>
<app-banner></app-banner>
<app-inicio *ngIf="router.url == '/'"></app-inicio>
<router-outlet></router-outlet>
<app-footer></app-footer>
Se están llamando a los componentes por sus directivas o selector.
En el componente inicio se está utilizando un componente estructural if, puede ver el detalle en la
presentación de “Directivas Angular”. En este caso para indicarle que solo se cargue en la ruta raíz o página
inicial.
El router-outlet, que indica donde deben mostrarse los componentes de salida o que llaman mediante rutas.
DEFINIR RUTAS
Es esencial especificar el orden de los imports en el módulo app, para que no interfiera con la carga de rutas,
esto va a depender de la jerarquía o estructura de módulos que tenga definido en la aplicación
app.module.ts
imports: [BrowserModule,
HomeModule,
VideojuegoModule,
CoreModule,
AppRoutingModule],
home.routing.module.ts
import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";
import { AcercadeComponent } from "./acercade/acercade.component";
5
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
{ path: "home/acercade", component: AcercadeComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class HomeRoutingModule {}
videojuego.routing.module.ts
import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";
import { VideojuegoIndexComponent } from "./videojuego-index/videojuego-index.component";
import { VideojuegoShowComponent } from "./videojuego-show/videojuego-show.component";
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class VideojuegoRoutingModule {}
Ahora defina la carga dinámica de las rutas en el archivo de rutas principal, además de las rutas generales.
Sintaxis Angular 8
app.routing.module.ts
6
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
const routes: Routes = [
{
path: "videojuego",
loadChildren: () =>
import("./videojuego/videojuego-routing.module").then(
mod => mod.VideojuegoRoutingModule
)
},
{
path: "home",
loadChildren: () =>
import("./home/home-routing.module").then(mod => mod.HomeRoutingModule)
},
{ path: "", redirectTo: "", pathMatch: "full" },
{ path: "**", component: PageNotFoundComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Sintaxis Angular 7
app.routing.module.ts
7
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
Para poder utilizar las rutas es necesario definir en el componente app, la utilización de la librería router y
cargarla como inyección de dependencia en el contructor.
app.component.ts
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
title = "Videojuegos";
constructor(public router: Router) {}
}
Además, es necesario que se puedan acceder las rutas desde el componente header, importando el archivo
de rutas principal en el módulo al que pertenece
core.component.ts
header.component.html
<li class="nav-item">
<a class="nav-link" [routerLink]="['/']" routerLinkActive="active"
>Inicio</a
>
</li>
<li class="nav-item">
8
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
<a
class="nav-link"
[routerLink]="['home/acercade']"
routerLinkActive="active"
>Acerca de</a
>
</li>
<li class="nav-item">
<a
class="nav-link"
[routerLink]="['videojuego']"
routerLinkActive="active"
>Videojuegos</a
>
</li>
Ver presentación “Data Binding Angular” para más detalle de los tipos de vinculación de datos de Angular.
En el componente de página no encontrada defina una vinculación de datos de evento de la siguiente forma.
page-not-found.component.html
page-not-found.component.ts
@Component({
selector: 'app-page-not-found',
templateUrl: './page-not-found.component.html',
styleUrls: ['./page-not-found.component.css']
})
export class PageNotFoundComponent implements OnInit {
constructor(private router:Router) { }
ngOnInit() {
}
irInicio(){
9
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
this.router.navigate(['/']);
}
}
Ejecute la aplicación con el comando
ng serve -o
Verifique que se puede navegar y acceder a la página no encontrada si se solicita en la url una ruta que no
existe.
MODELOS
Para gestionar la información del videojuego es necesario definir las entidades con los atributos necesarios,
para cumplir a cabalidad con este aspecto es necesario comprender como está estructurada la información
del API.
ng g interface share/models/VideojuegoEntidad
ng g interface share/models/UserEntidad
ng g interface share/models/PlataformaEntidad
ng g interface share/models/LikeEntidad
ng g interface share/models/Videojuego
Las entidades tienen definidos inicialmente solo los campos que están definidos en la base datos, el otro
modelo en este caso Videojuego define como se obtienes los videojuegos del API, conforme se avance en la
construcción de la aplicación faltaran atributos para obtener todos los datos que se gestiona.
SERVICIO
Lea la presentación “Servicios Angular”, para comprender los aspectos que lo conforman.
Para poder acceder al API es necesario utilizar el módulo del Cliente HTTP, importándolo en app.module
imports: [
BrowserModule,
// importar HttpClientModule después BrowserModule.
HttpClientModule,
11
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
videojuego.service.ts
@Injectable({
providedIn: "root"
})
export class VideojuegoService {
ServerUrl = environment.apiURL;
errorData: {};
console.error(
`Error código ${error.status}, ` + `,detalle: ${error.error}`
);
}
this.errorData = {
errorTitle: "Falló la solicitud",
errorDesc: "Ocurrió un inconveniente. Inténtelo de nuevo más tarde"
};
return throwError(this.errorData);
}
}
Cuando se utilicen observables o se utilice un servicio que consume un API, es importante tener en cuenta el
ciclo de vida de Angular, porque cuando se carga la plantilla y después se resuelve el observable, por este
motivo es importante acceder a las propiedades que se evalúen con directivas de Angular por medio del
operador Elvis, que es una variante del operador condicional ternario, este es un operador binario que
devuelve su primer operando si ese operando se evalúa a un valor verdadero, es decir, permite verificar la
existencia de un objeto antes de intentar acceder a su propiedades con las interpolaciones.
*ngIf="datos?.videojuego"
videojuego-index.component.ts
@Component({
selector: "app-videojuego-index",
13
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
templateUrl: "./videojuego-index.component.html",
styleUrls: ["./videojuego-index.component.css"]
})
export class VideojuegoIndexComponent implements OnInit {
datos: Videojuego;
error: {};
constructor(private videojuegoService: VideojuegoService) {}
//Filtro
ngOnInit() {
//suscripción para uso del servicio
this.videojuegoService
.getVideojuegos()
.subscribe(
(respuesta: Videojuego) => (this.datos = respuesta),
error => (this.error = error)
);
}
}
videojuego-index.component.html
<div class="tituloBanner">
<div class="col-lg-12 mx-auto">
<div class="site-heading">
<h1>Lista de Videojuegos</h1>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="card ">
<div class="card-body">
<div class="row">
<div class="col-md-2">Buscar:</div>
<div class="col-md-4">
<input type="text" />
</div>
</div>
<div class="row">
<div class="col-md-6">
<h4>Filtrado por:</h4>
</div>
</div>
14
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Videojuego</th>
<th>Fecha Estreno Inicial</th>
<th>Likes</th>
<th>Detalle</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let vj of datos?.videojuegos">
<td>{{ vj.nombre }}</td>
<td>
{{ vj.created_at | date: "dd-MM-yyyy" }}
</td>
<td>
{{ vj.promedioLikes }}
</td>
<td>
<a [routerLink]="['/videojuego/', vj.id]">Detalle</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Para obtener un videojuego, agregue el siguiente método después del de listar videojuegos
Videojuego.service.ts
15
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
}
Falta utilizarlo en el componente
videojuego-show.component.ts
@Component({
selector: "app-videojuego-show",
templateUrl: "./videojuego-show.component.html",
styleUrls: ["./videojuego-show.component.css"]
})
export class VideojuegoShowComponent implements OnInit {
datos: VideojuegoEntidad;
error: {};
constructor(
private route: ActivatedRoute,
private router: Router,
private videojuegoService: VideojuegoService
) {}
ngOnInit() {
let id = +this.route.snapshot.paramMap.get("id");
//suscripción para uso del servicio
this.videojuegoService
.getVideojuego(id)
.subscribe(
(respuesta: VideojuegoEntidad) => (this.datos = respuesta),
error => (this.error = error)
);
}
onBack(): void {
this.router.navigate(["/videojuego"]);
}
}
videojuego-show.component.html
<div class="tituloBanner">
<div class="col-lg-12 mx-auto">
<div class="site-heading">
16
Carrera Ingeniería del Software – Sede Central
Profesora: Nathalie Paniagua López
Curso: ISW- 811 Aplicaciones Web utilizando Software Libre
Año: 2019 Ciclo lectivo: II
<h1 *ngIf="datos?.msg">{{ datos.msg }}</h1>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="card col-lg-12" *ngIf="datos?.videojuego">
<div class="card-body">
<h5 class="card-title">{{ datos.videojuego.nombre }}</h5>
<p class="card-text">{{ datos.videojuego.descripcion }}</p>
<p class="card-text">
<small class="text-muted">{{
datos.videojuego.created_at | date: "dd-MM-yyyy"
}}</small>
</p>
</div>
<div class="card-footer text-muted">
{{ datos.videojuego.promedioLikes }}
</div>
<div class="card-footer">
<button class="btn btn-outline-secondary" (click)="onBack()">
<i class="fa fa-chevron-left"></i> Regresar
</button>
</div>
</div>
</div>
</div>
17