SlideShare una empresa de Scribd logo
Sección 5 Expandir Angular
Centro público integrado de formación profesional
Nuevo (desglose IES Campanillas)
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
¿Qué veremos en esta sección?
Una vez sentadas las bases de Angular en la sección anterior, vamos a seguir
expandiéndolas aquí, con los siguientes temas: Crear proyectos de Angular
1. Profundizar un poco más en los módulos
2. FormsModule
3. ngModel
4. @Inputs
5. @outputs
6. Servicios
7. Métodos en servicios
8. Depuraciones
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Temas puntuales de la sección
Aunque todo lo que vamos a a tratar es opcional, la
mayor parte de aplicaciones de Angular usan en
cierto punto cada uno de los temas que están en
esta sección.
La idea es comprender bien los conceptos para que
siempre nos suenen y saber siempre, de donde
viene, que cosa.
Continuación del
proyecto
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué necesitamos?
Lo primero es descargar nuestro proyecto desde GitHub.
Creamos un directorio de trabajo, entramos dentro y en la terminal ejecutamos:
# clonar https://github.com/jg...74/02...es.git/
Entramos dentro del directorio y abrimos VSC
# code .
En VSC deberíamos de ver algo tal que así ––––>
Nota: La idea es tener nuestro código en GitHub, bien ordenado, documentado y
listo para mostrar a quien tenga interés.
No olvidemos que GitHub y LindIn, son nuestro porfolio.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Continuación del proyecto
• ¿Qué necesitamos?
A continuación, construimos nuestro proyecto gracias a los paquetes:
- package.json,
- Package.lock.json
# npm install
Por último, levantamos el servidor:
# ng serve
En resumen, estos son los pasos que hay que realizar para probar cualquier
proyecto Angular que encontremos en GitHub o en cualquier otro repositorio.:
- Clonar
- Reconstruir
- Servir
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Continuación del proyecto
Módulo DBZ
(Dragon Ball Z)
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué necesitamos?
Comenzamos creando el módulo ’dbz’ ç
¿Recuerdas como se crea un módulo?
Dentro de la carpeta del proyecto escribimos lo siguiente en la terminal:
# ng g m dbz
Consultar la hoja de Atajos: Comandos para generar componentes...
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Continuación del proyecto
• ¿Qué observamos?
Tenemos:
- Definición de la clase módulo,
- Decorador de la clase módulo,
- Importaciones de los módulos que necesitamos; NgModule, CommonModule
Nota. En este caso CommonModule, no es necesario.
A continuación creamos los siguientes directorios dentro de ‘dbz’:
- components, vistos en la Sección 4, para guardar los pequeños componentes de ‘dbz’
- interfaces, que son muy parecidas a las de TS
- pages, no es más que un componente, que agrupa componentes (páginas de navegación)
- services, (todavía no sé que son… ya lo veremos)
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Continuación del proyecto
• ¿Qué observamos?
Dentro de ‘pages’ creamos el archivo ‘main-page.component.ts’.
¿Recuerdas como se crea un componente?
Dentro del archivo comenzamos a escribir a-com… y pulsamos Tab o Enter.
En el código del esqueleto del componente modificamos lo siguiente:
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Continuación del proyecto
• TAREA
Debemos aplicar los cambios necesarios para usar el componente, ‘main-page’
Pensemos lo que debemos tener en cuenta:
- ¿Hemos declarado y exportado el componente
‘MainPageComponent’ en ‘dbz.module.ts’?
- ¿Hemos importado el módulo
‘DbzModule’ en ‘app.module.ts’
- Por último, y no menos importante,
¿estamos usando el selector
‘app-dbz-main-page’ en ‘app.component.html’?
Digamos que hemos recorrido las dependencias desde dentro hacia fuera.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Continuación del proyecto
• TAREA
Visualmente sería algo así (desde dentro hacia fuera):
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Continuación del proyecto
app.module.ts
import { … } from ‘./…’;
imports: […]
app.component.html
<…></…>
<hr>
<app-counter></app-counter>
<hr>
<app-heroes-hero></app-heroes-hero>
<hr>
<app-heroes-list></app-heroes-list>
dbz.module.ts
import { … } from ‘./…’;
declarations: […],
exports: […]
main-page-component.ts
selector: ‘…’
templeUrl: ‘./…’
• SOLUCIÓN
Visualmente sería algo así (desde dentro hacia fuera):
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Continuación del proyecto
app.module.ts
import { … } from ‘./…’;
imports: [DbzModule]
app.component.html
<app-dbz-main-page></app-dbz-main-page>
<hr>
<app-counter></app-counter>
<hr>
<app-heroes-hero></app-heroes-hero>
<hr>
<app-heroes-list></app-heroes-list>
dbz.module.ts
import { … } from ‘./…’;
declarations: [MainPageComponent],
exports: [MainPageComponent]
main-page-component.ts
selector: ‘…’
templeUrl: ‘./…’
• ¿Qué observamos?
El componente de DBZ no es un ‘stand-alone-component module’ así que
tenemos que declararlo y exportarlo para que pueda ser usado.
Se importa el módulo del cuál depende el componente DBZ, para poder hacer uso
de él en la aplicación.
Haciendo esto último simplificamos las dependencias de nuestra aplicación, porque
para los sucesivos componentes que declaremos en el módulo, estos ya quedaran
importados y listos para ser usados.
Por favor, pensad en Angular como la evolución que hubo desde la arquitectura
clásica (estilo romano) (dondé los muros soportaban la carga del techo), a la Gótica
(dónde la carga la soportaban los pilares)
En el primero las ventanas eran pequeñas, en el segundo se posibilitó la creación
de esas vidrieras tan grandes y coloridas.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Continuación del proyecto
Diseño de la
pantalla
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• TAREA Diseñar la pantalla para nuestra aplicación: Dragon Ball Z
¿Serían capaces de crear algo así?
Escribimos el siguiente código en ‘main-page.component.html’:
siguiente diapositiva…
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Diseño de la pantalla
• SOLUCIÓN
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Diseño de la pantalla
Pensemos en
componentes
pequeños
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué necesitamos?
Necesitamos empequeñecer el código anterior, debemos sintetizarlo de tal modo
que la función resultante del componente, podamos reutilizarla en otro lugar.
Ejemplo:
Mandar los datos necesarios a un componente ‘lista’.
Comencemos creando un componente de ‘lista de personajes’.
Recordemos las dos formas que hemos aprendido para crear un componente:
- Desde (CLI): # ng g c <…>
- Manualmente:
creamos el archivo ‘<…>component.ts’ y
dentro del archivo añadimos el código escribiendo ‘a-compone + Tab’
Aprendamos una tercera forma.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Pensemos en componentes pequeños
• ¿Qué necesitamos?
1 2 Nombre del componente: ‘list’
3 Default component
4 Confirm
5 Debemos tener algo tal que así:
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Pensemos en componentes pequeños
• ¿Qué necesitamos?
Pasos:
1.- Añadimos dbz… al nombre del selector, ‘dbz-list’
Esto hace que el componente tenga más sentido en nuestra aplicación.
2.- Comprobamos que el componente ‘ListComponent’ está declarado en
‘dbz.module.ts’ y podemos hacer uso de este en ‘main-page-component.ts’
3.- En ‘main-page-component.ts’ sustituimos el código del listado por:
<dbz-list></dbz-list>
4.- Pegamos el código del listado en ‘list-component.html’
Si todo está correcto, nada debió de cambiar en el navegador, pero…
ahora podemos hacer uso de esa lista de personajes en cualquier otro lugar.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Pensemos en componentes pequeños
• TAREA
Crear el componente ‘add-carácter’ para la parte del código del formulario.
Sigue los pasos realizados para el componente lista.
Recuerda añadir dbz… al nombre del selector una vez creado.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Pensemos en componentes pequeños
• SOLUCIÓN
1 2
3 4
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Pensemos en componentes pequeños
@Input()
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué necesitamos?
Un decorador de componentes que permite la comunicación entre padre e hijo.
Permite que un componente padre, ‘main-page.component.ts’ envie información a
sus componentes hijos: ‘list.component.ts’, ‘add-character.component.ts’, etc…
Definimos el decorador @Input() en el componente ‘list.component.ts’ para que
muestre los datos de personajes que le proporcionará ‘main-page.component.ts’
La idea es que la página principal envie los datos que quiera mostrar a los
diferentes componentes que la implementen.
Archivos involucrados:
main-page.component.ts/html =>(datos)=> list.componet.ts/html + interfaz(Character)
Escribimos el siguiente código en los archivos correspondientes:
siguiente diapositiva…
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Input()
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Input()
Uso del Decorador @Input() para la comunicación de datos
desde el componente padre, al componente hijo
character.interface.ts
export interface Character {
name: String;
power: number;
}
main-page.component.ts
import { Character } from '../interfaces/character.interface’;
…
export class MainPageComponent {
public characters: Character [] =[{
name: 'Krillin’,
power: 1000
},{
name: 'Goku’,
power: 9500
},{
name: 'Vegeta’,
power: 7500
}];
}
list.component.ts
import { Component, Input } from '@angular/core’;
import { Character } from '../../interfaces/character.interface';
…
export class ListComponent {
@Input() // No olvidar importar el decorador Input
public characterList: Character[] = [{
name: 'Trunks’,
power: 10
}]
}
main-page.component.html
<dbz-list [characterList]="characters"></dbz-list>
list.component.html
…
<li *ngFor="let character of characterList"
class="list-group-item">
<strong>name: </strong> <span>{{character.name}}</span> -
<strong>Power: </strong> <span>{{character.power}}</span>
</li>
…
1
2
3
El tipo
Character está
definido por
esta interfaz
[characterList]="characters” e @Input() hacen posible la comunicación
• ¿Qué observamos?
Veamos una representación gráfica de lo que ocurre.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Input()
main-page.component.html/ts
list.component.html/ts
.html
…
<li *ngFor="let character of characterList"
class="list-group-item">
.ts
import { …, Input } from '@angular/core';
import { Character } from '../../interfaces/character.interface';
…
export class ListComponent {
@Input() // No olvidar importar el decorador Input
public characterList: Character[] = [{
…
.html
<dbz-list [characterList]="characters"></dbz-list>
.ts
import { Character } from '../interfaces/character.interface’;
…
export class MainPageComponent {
public characters: Character [] =[{
…
• ¿Qué observamos?
De la misma forma que la interpolación, permiten la comunicación entre los
archivos :
- list.component.ts
- *ngFor="let character of characterList"
- <strong>name: </strong> <span>{{character.name}}</span>
- list.component.html
- public characterList: Character[] = [{ name: 'Trunks’,
El Decorador, permite la comunicación entre los archivos.
- list.component.ts
- @Input()
- public characterList: Character[] = [{
- main-page.component.html
- <dbz-list [characterList]="characters"></dbz-list>
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Input()
Expandiendo
*ngFor
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué necesitamos?
La directiva ‘ngFor()’ nos ayuda a crear esos elementos HTML que se repiten en
tiempo de ejecución, pero…
¿Tiene ‘ngFor()’ algún índice que podemos usar para referenciar dichos
elementos?
Estos son los principales: index, first, last, eve, odd…
Escribimos el siguiente código en los archivos correspondientes:
siguiente diapositiva…
El siguiente Recurso muestra las variantes de diseño de listas en Bootstrap.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Expandiendo *ngFor()
• ¿Qué necesitamos?
list.component.html
<li *ngFor="let character of characterList; let i=index; let isFirst = first; let isLast = last;
let isEven = even; let isOdd = odd;
"class="list-group-item">
<span class="text-primary">{{i}}. </span>
<strong>Name: </strong> <span>{{character.name}}</span> -
<strong>Power: </strong> <span>{{character.power}}</span><br />
<span>Es el primero: {{isFirst}}</span><br />
<span>Es par: {{isEven}}</span><br />
<span>Es impar:{{isOdd}}</span><br />
<span>Es el último: {{isLast}}</span>
</li>
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Expandiendo *ngFor()
ngClass – Clases
basado en
condiciones
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué necesitamos?
Es normal que en tiempo de ejecución queramos que los objetos se presenten de
un modo u otro, e incluso que los datos del mismo objeto, tengan
representaciones diferentes.
A continuación dos técnicas para cambiar la visualización de los datos:
Escribimos el siguiente código en el archivo ‘list.component.html’:
siguiente diapositiva…
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – ngClass – Clases (basado en condiciones)
• ¿Qué necesitamos?
TÉCNICA 1 Hacemos uso de las clases
<h4>Listado</h4>
<ul class="list-group">
<li *ngFor="let character of characterList;
let i=index; let isFirst = first; let isLast = last; let isEven = even; let isOdd = odd;"
class="list-group-item {{ isFirst?'list-group-item-success’:
isEven?'list-group-item-primary’:
isLast?'list-group-item-dark’:’’ }}">
<span class="text-primary">{{i+1}}. </span>
<strong>Name: </strong> <span>{{character.name}}</span> -
<strong>Power: </strong> <span>{{character.power}}</span>
</li>
</ul>
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – ngClass – Clases (basado en condiciones)
• ¿Qué necesitamos?
TÉCNICA 2 Hacemos uso de la directiva ‘ngClass’
<h4>Listado</h4>
<ul class="list-group">
<li *ngFor="let character of characterList;
let i=index; let isFirst = first; let isLast = last; let isEven = even; let isOdd = odd;"
class="list-group-item"
[ngClass]="{ 'list-group-item-success': isFirst, 'list-group-item-primary': isEven, 'list-group-item-dark': isLast }">
<span class="text-primary">{{i+1}}. </span>
<strong>Name: </strong> <span>{{character.name}}</span> -
<strong>Power: </strong> <span>{{character.power}}</span>
</li>
</ul>
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – ngClass – Clases (basado en condiciones)
• ¿Qué observamos?
Angular nos ayuda a simplificar la lógica de programación.
La estructuración del código clarifica el código.
Es verdad que tenemos que adaptarnos a un nivel de abstracción:
- aprender dónde está cada cosa,
- como son las relaciones entre los diferentes objetos,
- herramientas del lenguaje, etc…
pero todo es para un propósito mayor:
- el código es más escalable,
- la programación en equipo se simplifica,
- hay un mayor control sobre lo que se programa (todo se verifica al momento)
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – ngClass – Clases (basado en condiciones)
FormsModule y
ngModel
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué necesitamos?
Comencemos a trabajar con formularios.
Sintaxis (one-way data-binding):
- (click), esperamos el suceso de eventos
Ejemplo: (click)="increaseBy(1)"
- [value], hacemos uso de los atributos
Ejemplo: [value]="character.name"
Consultar la hoja de Atajos: FormsModule de @angular/forms
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – FormsModule y ngModel
• ¿Qué necesitamos?
Sintaxis (two-way data-binding):
- [(ngModel)], con esta directiva conseguimos:
- escuchar el evento de cambio/acción sobre el objeto que se aplica.
- cambiar los valores del código que programa el objeto que mostramos.
Ejemplo: [(ngModel)]="character.name"
Escribimos el siguiente código en los archivos:
- ‘add-cha.component.html/ts’,
- ‘dbz.module.ts’
siguiente diapositiva…
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – FormsModule y ngModel
• ¿Qué necesitamos?
Muy importante, no olvidar importar el módulo para la gestión de formularios.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – FormsModule y ngModel
• ¿Qué necesitamos?
Muy importante, usar el intellisense para que automáticamente haga el ‘import’
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – FormsModule y ngModel
• ¿Qué observamos?
Error. Dos formas de resolverlo:
- Este error nos indica que hemos olvidado el atributo que los inputs suelen llevar
a la hora de formar parte de un formulario.
- De no querer hacerlo así tendremos que definir el formulario como un
stand-alone.component.
Este se debe a que Angular intenta por todos los medios controlar todos y cada
uno de los objetos con los que tratamos, ya sea bien en el .ts (con el control de
tipos) o bien en el .html (gestionando las referencias de los mismos, así como los
valores que poseen)
- Añadimos el atributo ’name’ a las etiquetas ‘input’
- Ahora sí vemos como el formulario muestra el contenido del atributo ‘character’
El error desaparece.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – FormsModule y ngModel
• ¿Qué necesitamos?
add-character.component.html add-character.component.ts
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – FormsModule y ngModel
• ¿Qué observamos?
La directiva ‘ngModel’ muestra los valores del atributo ‘character’ gracias a los
atributos que hemos añadido en las etiqueta input (one-way binding)
Cuando modificamos los valores estos se modifican automáticamente en el atributo
‘character’ (two-way binding), tal y como se puede comprobar con el método
‘emitCharacter()’ que hemos implementado.
Cuando pulsamos en el botón ‘Agregar’ ya no se produce el refresco propio de los
formularios con ‘submit’
El evento ‘click’ hace que el botón cumpla su función pero no es ese el lugar
correcto para colocarlo, dado que estamos trabajando con un formulario.
Lo correcto es capturar el evento en el propio formulario.
(En el próximo apartado lo modificaremos)
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – FormsModule y ngModel
@Output()
Emitir eventos al
padre
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué necesitamos?
Un decorador de componentes que permite la comunicación entre hijo y padre.
Permite que un componente hijo, ‘add-character.component.ts’ envie información
a su componente padre: ‘main-page.component.ts’
Definimos el decorador @Output() en el componente
‘add-character.component.ts’ para que emita un evento, producto de haber
agregado un nuevo personaje, que enviará a ‘main-page.component.ts’
La idea es que la página principal reciba el nuevo dato que hemos introducido en el
componente.
Archivos involucrados:
add-character.component.ts/html =>(evento+datos)=> main-page.componet.ts/html
Escribimos el siguiente código en los archivos correspondientes:
siguiente diapositiva…
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Output() Emitir eventos al padre
• ¿Qué necesitamos?
Comencemos cambiando el evento del botón.
Podríamos poner en el ‘form’ algo tal que así:
<form class="row" (click)="emitCharacter()">
Pero… aprendamos una nueva directiva: ‘ngSubmit’
<form class="row" (ngSubmit)="emitCharacter()">
También, evita que se recargue la página.
Por último, limpiamos el formulario en el método ‘emitCharacter()’
emitCharacter():void {
console.log(this.character);
this.character.name=’’;
this.character.power=0;
}
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Output() Emitir eventos al padre
• ¿Qué necesitamos?
Trabajemos ahora con el decorador @Output()
Básicamente se trata de una función que le permitirá al padre atender los eventos
del hijo.
En nuestro ejemplo:
- Si agregamos un personaje (add-character.component.html/ts) [hijo],
- Se actualiza la página principal (main-page.component.html/ts) [padre]
Una vez se actualiza la página principal Angular propagará los cambios
automáticamente para que el ‘list.component.html/ts’ muestre correctamente los
datos.
Consultar la hoja de Atajos: @Output y RxJS (subscripciones)
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Output() Emitir eventos al padre
• ¿Qué necesitamos?
Creamos un objeto que va a
- emitir el personaje nuevo que hemos añadido en el componente
‘add-character.component.ts’ [hijo],
- enviándolo al componente
‘main-page.component.ts’ [padre]
Para eso hacemos uso de la clase ‘EventEmitter’, su método ‘.emit’ y del
decorador ‘@Output()’
Escribimos el siguiente código en los archivos:
- ‘add-character.component.html/ts’,
- ‘main-page.component.html/ts’
siguiente diapositiva…
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Output() Emitir eventos al padre
• ¿Qué necesitamos?
add-character.component.ts
import { Component, EventEmitter, Output } from '@angular/core’;
…
export class AddCharacterComponent {
@Output()
public onNewCharacter:EventEmitter<Character> = new EventEmitter();
…
emitCharacter():void {
…
this.onNewCharacter.emit(this.character);
Por favor, no olvidéis de hacer uso del intellisense, este añadirá automáticamente
la clase al ‘import’
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Output() Emitir eventos al padre
• ¿Qué necesitamos?
Ahora necesitamos recibir dicho personaje en nuestra página principal
Creamos un método que va a
- recibir el personaje nuevo que hemos añadido en el componente
‘add-character.component.ts’ [hijo],
- usandolo en el componente
‘main-page.component.ts’ [padre]
Y… ¿cómo recibo el valor de ‘character’ en el método que uso en el .html?
Para eso hacemos uso de ‘$event’
$event, al igual que en JavaScript, es un evento global, propio de los eventos,
que que forma parte del lenguaje TS y del que siempre podemos disponer, aún sin
haberlo creado. Contiene absolutamente toda la información referente al evento,
quien lo originó, cuando, dónde, circunstancias…
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Output() Emitir eventos al padre
• ¿Qué necesitamos?
main-page.component.html
<dbz-add-character (onNewCharacter)="onNewCharacter($event)"></dbz-add-character>
main-page.component.ts
onNewCharacter(character: Character): void {
console.log("MainPage");
console.log("character");
}
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Output() Emitir eventos al padre
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Output() Emitir eventos al padre
Uso del Decorador @Output() para la emisión eventos y datos
desde el componente hijo, al componente padre
add-character.component.ts
import { …, EventEmitter, Output } from '@angular/core’;
…
export class AddCharacterComponent {
@Output()
public onNewCharacter:EventEmitter<Character> = new
EventEmitter();
…
emitCharacter():void {
…
this.onNewCharacter.emit(this.character);
…
main-page.component.ts
…
onNewCharacter(character: Character): void {
console.log("MainPage");
console.log("character");
}
add-character.component.html
…
<form class="row" (ngSubmit)="emitCharacter()">
main-page.component.html
…
<dbz-add-character
(onNewCharacter)="onNewCharacter($event)"></dbz-add-
character>
• ¿Qué observamos?
Veamos una representación gráfica de lo que ocurre.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – @Output() Emitir eventos al padre
main-page.component.html/ts
add-character.component.html/ts
.ts
import { Component, EventEmitter, Output } from '@angular/core’;
…
export class AddCharacterComponent {
@Output()
public onNewCharacter:EventEmitter<Character> = new EventEmitter();
…
emitCharacter():void {
…
this.onNewCharacter.emit(this.character);
…
.html
…
<dbz-add-character
(onNewCharacter)="onNewCharacter($event)"></dbz-add-
character>
.ts
…
onNewCharacter(character: Character): void {
console.log("MainPage");
console.log("character");
}
Formas de depurar
la app
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué necesitamos?
1.- Devtools de Angular
Las herramientas de desarrollo de React y Vue están más logradas pero Angular
tiene un Framework mucho más elaborado.
Es cuestión de tiempo que Angular mejore ese aspecto.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Formas de depurar la app
• ¿Qué necesitamos?
2.- debugger; Con esta instrucción paramos la ejecución/interpretación del código
y posicionándonos encima de los objetos podremos ver los valores.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Formas de depurar la app
• ¿Qué observamos?
3.- breakpoints En la misma interfaz, podemos establecer puntos de interrupción
para ir paso a paso y ver el estado de los objetos.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Formas de depurar la app
Añadir personaje al
listado
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué necesitamos?
Tan simple como esto:
onNewCharacter(character: Character): void {
this.characters.push(character);
}
Como se comentó, Angular propagará dicho valor entre los diferentes componentes
que hagan uso del mismo.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Añadir personaje al listado
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Añadir personaje al listado
Uso del Decorador @Output() para la emisión eventos y datos
desde el componente hijo, al componente padre
add-character.component.ts
import { …, EventEmitter, Output } from '@angular/core’;
…
export class AddCharacterComponent {
@Output()
public onNewCharacter:EventEmitter<Character> = new
EventEmitter();
…
emitCharacter():void {
…
this.onNewCharacter.emit(this.character);
…
main-page.component.ts
…
onNewCharacter(character: Character): void {
this.characters.push(character);
}
add-character.component.html
…
<form class="row" (ngSubmit)="emitCharacter()">
main-page.component.html
…
<dbz-add-character
(onNewCharacter)="onNewCharacter($event)"></dbz-add-
character>
• ¿Qué observamos?
Veamos una representación gráfica de lo que ocurre.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Añadir personaje al listado
main-page.component.html/ts
add-character.component.html/ts
.html
(ngSubmit)="emitCharacter()”
.ts
import { Component, EventEmitter, Output } from '@angular/core’;
…
export class AddCharacterComponent {
@Output()
public onNewCharacter:EventEmitter<Character> = new EventEmitter();
…
emitCharacter():void {
…
this.onNewCharacter.emit(this.character);
…
.html
…
<dbz-list [characterList]="characters"
(onDeleteIndex)="onDeleteIndex($event)"></dbz-list>
.ts
…
onNewCharacter(character: Character): void {
this.characters.push(character);
}
• ¿Qué necesitamos?
Hemos añadido elementos a la lista.
¿Qué tal si los borramos?
Añadimos el botón de eliminar a cada componente:
El siguiente Recurso muestra el uso del método ‘.splice()’ de arrays.
Eliminar elementos de una lista.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Eliminar personaje del listado
• TAREA
Emitir el índice del personaje sobre el cual se ha pulsado el botón eliminar en el
componente, ‘list.component.html/ts’
Recordemos lo que hicimos al emitir el ‘character’ que queríamos insertar:
- capturar el evento, ‘list.component.html’ y
<button
(click)="emitIndex(i)"
- manejarlo con el método ‘emitIndex(i)’, ‘list.component.ts’
@Output()
public onDeleteIndex:EventEmitter<number> = new EventEmitter();
emitIndex(index: number): void {
this.onDeleteIndex.emit(index);
}
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Eliminar personaje del listado
• SOLUCIÓN
list.component.html
…
<button
(click)=”emitIndex(i)"
class="btn btn-danger">X</button>
</li>
list.component.ts
…
emitIndex(index: number): void {
console.log({index});
}
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Eliminar personaje del listado
• TAREA
Ahora que tenemos el índice del elemento que queremos borrar debemos emitirlo a
través de un evento de Emisión, para que:
- el componente ‘main-page.component.ts’ lo capture, y
- a través de un método ‘onDeleteIndex(index)’ borre el personaje.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Eliminar personaje del listado
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Añadir personaje al listado
Uso del Decorador @Output() para la emisión eventos y datos
desde el componente hijo, al componente padre
list.component.ts
import { …, EventEmitter, Output } from '@angular/core’;
…
@Output()
public onDeleteIndex:EventEmitter<number> = new EventEmitter();
emitIndex(index: number): void {
this.onDeleteIndex.emit(index);
}
…
main-page.component.ts
…
onDeleteIndex(index: number): void {
this.characters.splice(index, 1);
}
list.component.html
…
<button
(click)="emitIndex(i)"
main-page.component.html
…
<dbz-list [characterList]="characters”
(onDeleteIndex)="onDeleteIndex($event)></dbz-list>
• SOLUCIÓN (ELIMINAR)
Veamos una representación gráfica de lo que tenemos que hacer al borrar.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Eliminar personaje del listado
main-page.component.html/ts
list.component.html/ts
.html
(ngSubmit)="emitIndex()”
.ts import {… EventEmitter, Output }
@Output()
public onDeleteIndex:EventEmitter<number> = new EventEmitter();
emitIndex(index: number):void {
this.onDeleteCharacter.emit(this.character);
}
.html
<dbz-list [characterList]="characters”
(onDeleteIndex)="onDeleteIndex($event)></dbz-list>
.ts
onDeleteIndex(index: number): void {
this.characters.splice(index, 1);
}
Servicios
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué observamos?
Hasta ahora hemos definido nuestros datos de personajes:
en ‘main-page.component.ts’, pero este no es el mejor sitio para hacerlo,
tampoco es correcto que tengamos nuestra lógica para editarlos, ya que puede que
en otro componente (otras páginas, del mismo nivel, ‘hermanos’) necesiten dicha
información, y compartir dicha información a ese nivel, es complicado.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Servicios
Personajes
public
characters:
Character[] =
[{
name: 'Krillin',
power:
75_000
},
{
name:
'Gohan',
power:
1_950_000
},
{
name:
'Piccolo',
power:
1_200_000
},
{
name: 'Goku',
power:
150_000_000
},
{
name:
'Vegeta',
power:
3_000_000
},
{
name: 'Frieza',
power:
120_000_000
},];
• ¿Qué necesitamos?
Para garantizar que los datos con los que trabajamos están encapsulados, son de
única instanciación y disponibles a todos los niveles usaremos los servicios
Singleton.
Los servicios Singleton en Angular se maneja mediante Inyección de dependencias
(DI, en inglés)
Y, ¿que es esto de la (DI)?
Pues, un patrón de diseño en el que se garantiza que los constructores de las
clases reciben los objetos ya instanciados, con lo que se garantiza la
composición en vez de la herencia.
El siguiente Recurso muestra el uso de los servicios Singleton.
Es decir, que una clase solo tengan una única instancia.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Servicios
• ¿Qué necesitamos? Ejemplo:
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Servicios
Sin Inyección de dependencias Con Inyección de dependencias
class Article{
constructor(){
this.user = new User(); // instancia
this.image = new Image(); // instancia
}
}
/* No es correcto que el constructor de la clase Article se
tenga que encargar de instanciar los elementos que la
constituyen: User e Image
Podemos hablar entonces de acoplamiento, si queremos
usar la Image en otros objetos no podríamos hacerlo */
class Article{
constructor(private user : User, private image: Image){}
}
/* Recuerda: esta es la definición corta de clase */
/* La definición tradicional sería esta: */
class Article{
private user : User;
private image : Image
constructor(user : User, image : Image){
this.image = image;
this.user = user;
}
}
new Article(new User(), new Image()); // instancias
Fuente: https://codigofacilito.com/articulos/angular-di
• ¿Qué necesitamos?
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Servicios
Con Inyección de dependencias
@NgModule({
providers: [User]
})
@Component({})
class Ejemplo{
// En este ejemp. User es el injector token
constructor(private user : User){}
}
• ¿Qué necesitamos?
Creamos el servicio:
- CLI, en línea de comando
- Angular schematic, botón derecho en carpeta ‘service’, pulsar: ‘Angular: Generate service’
- A mano, creando los archivos: .html, .ts, etc…
Hagámoslo a mano:
Creamos el archivo: ‘dbz.services’
Escribimos el siguiente código en los archivos correspondientes:
siguiente diapositiva…
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Servicios
• ¿Qué necesitamos?
dbz.service.ts
Escribimos: a-ser… y vemos como aparecen todos los componentes disponibles.
Elejimos: a-service y automáticamente nos escribe:
import { Injectable } from '@angular/core';
@Injectable({providedIn: 'root’})
export class ServiceNameService {
constructor() { }
}
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Servicios
• ¿Qué necesitamos?
Como hasta ahora, con cualquier componente, un servicio es una clase.
@Inyectable, le dirá a angular que trate a la clase como un servicio.
Todos los servicios en Angular, desde la versión 6, implementan ‘providedIn: ‘root’
Sin o lo tuviera tendríamos que definirlo en la parte de los ‘providers’ en el archivo
‘app.module.ts’
Con esto, Angular define al servicio con un ‘Singleton’ en todo el proyecto.
Es decir, no importa dónde yo use ese servicio que, siempre que solicite el valor de
la instancia, mediante Inyección de dependencias, obtendré los mismos datos, el
mismo contenido, los mismos valores.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Servicios
• ¿Qué necesitamos?
Modificamos el siguiente fichero:
dbz.service.ts
import { Injectable } from '@angular/core';
import { Character } from '../interfaces/character.interface';
@Injectable({
providedIn: 'root'
})
export class DbzService {
public characters: Character[] = [{
name: 'Krillin’,
power: 75_000
}…
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Servicios
Sí, nos hemos traído todo el contenido de la clase en:
‘main-page.component.ts’
y lo hemos pegado en la clase del servicio ‘dbz.service.ts’
• ¿Qué necesitamos?
Modificamos el siguiente fichero:
main-page.component.ts
import { Component } from '@angular/core';
import { Character } from '../interfaces/character.interface';
import { DbzService } from '../services/dbz.sevice’;
@Component({
selector: 'app-dbz-main-page',
templateUrl: './main-page.component.html'
})
export class MainPageComponent {
constructor(public dbzService: DbzService) { }
}
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Servicios
• ¿Qué necesitamos?
Modificamos el siguiente fichero:
main-page.component.ts
<dbz-list [characterList]="dbzService.characters"
(onDeleteIndex)="dbzService.onDeleteIndex($event)"></dbz-list>
</div>
<div class="col">
<dbz-add-character (onNewCharacter)="dbzService.onNewCharacter($event)"></dbz-add-character>
</div>
…
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Servicios
Paquetes externos
uuID
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué observamos?
Recordemos que seguimos con el problema de borrar los elementos de la lista en
base al índice que ocupan en el array (o índice de cualquier objeto que lo
implemente)
Los id’s deben de ser únicos para cada personaje.
Si la implementación es correcta, los id’s únicos deben ser algo que quede a cargo
de algún paquete de instalación del proyecto, así nos eximimos de la
responsabilidad de tener colisiones a la hora de identificar a los elementos.
El siguiente Recurso es un paquete para Angular que nos ayuda a generar id’s
únicos con cierto formato.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
• ¿Qué observamos?
Para Angular existe un paquete que nos ayuda a crear id únicos: ‘uuid’
Instalémoslo:
# npm i uuid
Usémoslo importándolo en el servicio ‘dbz.service.ts’:
import { } from 'uuid’;
Vemos que se produce un error por dependencias
Resolvámoslo instalando la dependencia que se nos indica en el error:
# npm i --save-dev @types/uuid
Ahora sí podemos usarlo correctamente en la importación:
import { v4 as uuid } from 'uuid’;
v4 as uuid, utiliza el generador ‘v4’ de id’s únicos con el álias ‘uuid’
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
• ¿Qué necesitamos?
Agreguemos un id único al objeto ‘Character’.
¿Recordáis dónde está implementado el tipo de dicho objeto ‘Character’?
Sí, en la interfaz ‘character.interface.ts’:
export interface Character {
id?: string;
name: String;
power: number;
}
Ya que no vamos a proceder a refactorizar toda la aplicación, lo dejamos como
opcional para no tener que cambiar todo el código… por ahora 
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
• ¿Qué necesitamos?
‘dbz.service.ts’
import { v4 as uuid } from 'uuid';
import { Character } from '../interfaces/character.interface';
@Injectable({
providedIn: 'root'
})
export class DbzService {
public characters: Character[] = [{
id: uuid(),
name: 'Krillin’,
…
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
• TAREA
En el servicio ‘dbz.service.ts’ implementamos el método ‘onDeleteId(id: string)’
con el siguiente código:
onDeleteId(id: string): void {
this.characters = this.characters.filter(character => character.id != id);
}
Vemos que nuestra aplicación ha dejado de funcionar.
Las tareas son:
1.- Arreglar los errores producto del la implementación del nuevo método.
2.- Hacer que el id sea obligatorio y no opcional.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
• SOLUCIÓN
1.- Arreglar los errores producto del la implementación del nuevo método.
’main-page.component.html’
<dbz-list [characterList]="dbzService.characters"
(onDeleteId)="dbzService.onDeleteId($event)"></dbz-list>
</div>
…
’main-page.component.ts’
Eliminamos el ‘import { Character }…’ El objeto ya no se usa en este componente.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
• SOLUCIÓN
2.- Hacer que el id sea obligatorio y no opcional.
‘dbz.service.ts’
onNewCharacter(character: Character): void {
// const newCharacter: Character = { id: uuid(), ...character } // operador 'spread’
this.characters.push(character);
}
// const newCharacter…
Se usó cuándo no teníamos implementado el ‘id’ en ‘add-character.component.ts’
public character: Character = {
id: uuid(),
name: 'Videl’,
power: 14_000
}
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
• SOLUCIÓN
2.- Hacer que el id sea obligatorio y no opcional.
‘list.component.html’
…
<button
(click)="emitId(character.id)"
class="btn btn-danger">X</button>
</li>
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
‘list.component.ts’
export class ListComponent {
@Output()
public onDeleteId:EventEmitter<string> = new
EventEmitter();
emitId(id: string): void {
this.onDeleteId.emit(id);
}
Servicio Privado
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué observamos?
Malas prácticas.
Recordemos que al implementar nuestro servicio, toda la lógica de control sobre el
listado de personajes, ‘main-page.component.ts’, migró a la clase de dicho
servicio, ‘dbz.service.ts’
En nuestro ‘main-page.component.ts’ solo quedó el constructor que instancia
dicho servicio mediante Inyección de dependencias.
export class MainPageComponent {
constructor(public dbzService: DbzService) { }
…
Este servicio se construyo como público y las buenas prácticas aconsejan que sea
privado, lo cuál implica que ya no tengo acceso al mismo desde
’main-page.componente.html’ o cualquier otro componente que lo importe.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
• ¿Qué observamos?
Buenas prácticas.
export class MainPageComponent {
constructor(private dbzService: DbzService) { }
…
Para hacer esto posible debemos crear métodos en la clase que sirvan de puente
para comunicarme con el servicio.
Escribimos el siguiente código en los archivos correspondientes:
siguiente diapositiva…
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
• ¿Qué necesitamos?
‘main-page.component.html’
…
(onDeleteId)="onDeleteId($event)"></dbz-list>
</div>
<div class="col">
<dbz-add-character (onNewCharacter)="onNewCharacter($event)"></dbz-add-character>
</div>
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
• ¿Qué necesitamos?
‘main-page.component.ts’
onNewCharacter(character: Character) {
this.dbzService.addCharacter(character); // refactorizo
}
onDeleteId(id: string): void {
this.dbzService.deleteCharacter(id); // refactorizo
}
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
• ¿Qué necesitamos?
‘dbz.service.ts’
addCharacter(character: Character): void {
this.characters.push(character);
}
deleteCharacter(id: string): void {
this.characters = this.characters.filter(character => character.id != id);
}
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
• TAREA (extra)
En esta aplicación de Dragón Ball Z hemos implementado:
- El mostrar los personajes (Listado),
- La creación de personajes (botón ‘Agregar’), y
- La eliminación de personajes (botón ‘X’)
La tarea consiste en implementar el botón ‘U’ (update), para modificar a un
personaje.
Angular 16+ Edición 2023 Sección 5
José García Angular 16+ Edición 2023
TS – Paquetes externos uuID
Respaldo en
Github
Angular 16+ Edición 2023 Sección 4
José García Angular 16+ Edición 2023
TS – Nuevo apartado
• ¿Qué necesitamos?
Guardamos nuestro proyecto en GitHub.
1.- ¿Tenemos cuenta en github.com?
- Si la tienes, recuerda el usuario y contraseña de tu cuenta.
- Si no la tienes, crea una cuenta en github.com, recuerda tu usuario y contraseña.
2.- En la terminal (dentro del directorio del proyecto) ’03-expandir-angular-DBZ’):
- # git init
- # git add .
- # git commit –m ‘Fin de la sección 4’
3.- Accedemos a github.com
4.- Creamos el repositorio: ’03-expandir-angular’
Angular 16+ Edición 2023 Sección 4
José García Angular 16+ Edición 2023
TS – Respaldo en Github
• ¿Qué necesitamos?
5.- Copiamos las instrucciones para:
‘push an existing repository from the command line’
6.- Volvemos a la terminal y aplicamos las instrucciones anteriores:
- # git remote add origin https://github.com/jgarmay674/03-expandir-angular.git
- # git branch -M main
- # git push -u origin main
Error: remote: Support for password authentication was removed on August 13, 2021. remote:
Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-
repositories#cloning-with-https-urls for information on currently recommended modes of
authentication. fatal: Authentication failed for ‘https://github.com/jgarmay674/02-angular-bases.git’
Angular 16+ Edición 2023 Sección 4
José García Angular 16+ Edición 2023
TS – Respaldo en Github
• ¿Qué necesitamos?
7.- Creamos un token, Personal Access Token (PAT)
1 2 3
- Genera un nuevo token (classic)
- Indica el uso del token y ‘No expiration’
- Pulsa el botón ‘Generar token’
Angular 16+ Edición 2023 Sección 4
José García Angular 16+ Edición 2023
TS – Respaldo en Github
• ¿Qué necesitamos?
8.- Ahora sí podemos ejecutar:
# git push -u origin main
Solicitará la siguiente información:
- Username (de github.com)
- Password (pegamos el token)
Guardar las credenciales:
Creamos el archivo ‘.netrc’ en el raíz. Contenido:
machine https://github.com/jg...74/02...es.git/
login jg…74
password ghp_NL…7c
Angular 16+ Edición 2023 Sección 4
José García Angular 16+ Edición 2023
TS – Respaldo en Github

Más contenido relacionado

PPTX
Vamos a desplejar Angular+ 16 con Netlify
PDF
Tutorial aprendiendo a programar
PDF
Tutorial aprendiendo a programar
PDF
Tutorial aprendiendo a programar
PDF
Tutorial aprendiendo a programar
PDF
Primeros pasos con Backbone js, por Xavier Aznar
PDF
Diseños de autopistas-ep2005
PDF
Pre entrega dance plan v2
Vamos a desplejar Angular+ 16 con Netlify
Tutorial aprendiendo a programar
Tutorial aprendiendo a programar
Tutorial aprendiendo a programar
Tutorial aprendiendo a programar
Primeros pasos con Backbone js, por Xavier Aznar
Diseños de autopistas-ep2005
Pre entrega dance plan v2

Similar a Expandiendo los conocimientos de Angular+16 (20)

PDF
Entrega final DancePlan
PDF
Pre entrega dance plan - claudia figueroa
PDF
2.1 android cep jaen 2014 estructura de aplicación
DOCX
C sharp manual
DOCX
C sharp manual
DOCX
C sharp manual[1]
DOCX
C sharp manual
PDF
Integración sistemasembebidosaplicacionesmóviles
PDF
Unidad stack tecnologico y Aptugo - Desafio (2).pdf
DOCX
Introducción a la programación del amigo bot
PDF
Node js mongo crud tareas
PPTX
Anderson polanco diapositivas
PDF
Reactvolution
PDF
Clase_01.pdf
DOC
GUIA DE LABORATORIO PHONE GAP JQUERY MOBILE CARGADO DE_DATOS_DE_REGISTROS...
PDF
inLab FIB MeteorJS workshop by uLab UPC - Telefonica I+D
PDF
Desarrollando mi primera App para Windows 8 con C#
PDF
Manual de InnerSoft CAD en español
PDF
El arte de programar c++ - versión 3.0
Entrega final DancePlan
Pre entrega dance plan - claudia figueroa
2.1 android cep jaen 2014 estructura de aplicación
C sharp manual
C sharp manual
C sharp manual[1]
C sharp manual
Integración sistemasembebidosaplicacionesmóviles
Unidad stack tecnologico y Aptugo - Desafio (2).pdf
Introducción a la programación del amigo bot
Node js mongo crud tareas
Anderson polanco diapositivas
Reactvolution
Clase_01.pdf
GUIA DE LABORATORIO PHONE GAP JQUERY MOBILE CARGADO DE_DATOS_DE_REGISTROS...
inLab FIB MeteorJS workshop by uLab UPC - Telefonica I+D
Desarrollando mi primera App para Windows 8 con C#
Manual de InnerSoft CAD en español
El arte de programar c++ - versión 3.0
Publicidad

Último (20)

PDF
COMUNICACION EFECTIVA PARA LA EDUCACION .pdf
PDF
OK OK UNIDAD DE APRENDIZAJE 5TO Y 6TO CORRESPONDIENTE AL MES DE AGOSTO 2025.pdf
PDF
Punto Critico - Brian Tracy Ccesa007.pdf
PDF
COMPLETO__PROYECTO_VIVAN LOS NIÑOS Y SUS DERECHOS_EDUCADORASSOS.pdf
PDF
Escuela de Negocios - Robert kiyosaki Ccesa007.pdf
PDF
biología es un libro sobre casi todo el tema de biología
PDF
Unidad de Aprendizaje 5 de Educacion para el Trabajo EPT Ccesa007.pdf
PDF
CONFERENCIA-Deep Research en el aula universitaria-UPeU-EduTech360.pdf
PDF
La Evaluacion Formativa en Nuevos Escenarios de Aprendizaje UGEL03 Ccesa007.pdf
PDF
ACERTIJO Súper Círculo y la clave contra el Malvado Señor de las Formas. Por ...
PDF
Guia de Tesis y Proyectos de Investigacion FS4 Ccesa007.pdf
PDF
Habitos de Ricos - Juan Diego Gomez Ccesa007.pdf
PDF
Breve historia de los Incas -- Patricia Temoche [Temoche, Patricia] -- Breve ...
PDF
Salvese Quien Pueda - Andres Oppenheimer Ccesa007.pdf
PDF
TRAUMA_Y_RECUPERACION consecuencias de la violencia JUDITH HERMAN
DOCX
Tarea De El Colegio Coding For Kids 1 y 2
DOCX
V UNIDAD - PRIMER GRADO. del mes de agosto
PDF
Conecta con la Motivacion - Brian Tracy Ccesa007.pdf
PDF
Educación Artística y Desarrollo Humano - Howard Gardner Ccesa007.pdf
PDF
GUIA DE: CANVA + INTELIGENCIA ARTIFICIAL
COMUNICACION EFECTIVA PARA LA EDUCACION .pdf
OK OK UNIDAD DE APRENDIZAJE 5TO Y 6TO CORRESPONDIENTE AL MES DE AGOSTO 2025.pdf
Punto Critico - Brian Tracy Ccesa007.pdf
COMPLETO__PROYECTO_VIVAN LOS NIÑOS Y SUS DERECHOS_EDUCADORASSOS.pdf
Escuela de Negocios - Robert kiyosaki Ccesa007.pdf
biología es un libro sobre casi todo el tema de biología
Unidad de Aprendizaje 5 de Educacion para el Trabajo EPT Ccesa007.pdf
CONFERENCIA-Deep Research en el aula universitaria-UPeU-EduTech360.pdf
La Evaluacion Formativa en Nuevos Escenarios de Aprendizaje UGEL03 Ccesa007.pdf
ACERTIJO Súper Círculo y la clave contra el Malvado Señor de las Formas. Por ...
Guia de Tesis y Proyectos de Investigacion FS4 Ccesa007.pdf
Habitos de Ricos - Juan Diego Gomez Ccesa007.pdf
Breve historia de los Incas -- Patricia Temoche [Temoche, Patricia] -- Breve ...
Salvese Quien Pueda - Andres Oppenheimer Ccesa007.pdf
TRAUMA_Y_RECUPERACION consecuencias de la violencia JUDITH HERMAN
Tarea De El Colegio Coding For Kids 1 y 2
V UNIDAD - PRIMER GRADO. del mes de agosto
Conecta con la Motivacion - Brian Tracy Ccesa007.pdf
Educación Artística y Desarrollo Humano - Howard Gardner Ccesa007.pdf
GUIA DE: CANVA + INTELIGENCIA ARTIFICIAL
Publicidad

Expandiendo los conocimientos de Angular+16

  • 1. Sección 5 Expandir Angular Centro público integrado de formación profesional Nuevo (desglose IES Campanillas) Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023
  • 2. ¿Qué veremos en esta sección? Una vez sentadas las bases de Angular en la sección anterior, vamos a seguir expandiéndolas aquí, con los siguientes temas: Crear proyectos de Angular 1. Profundizar un poco más en los módulos 2. FormsModule 3. ngModel 4. @Inputs 5. @outputs 6. Servicios 7. Métodos en servicios 8. Depuraciones Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Temas puntuales de la sección Aunque todo lo que vamos a a tratar es opcional, la mayor parte de aplicaciones de Angular usan en cierto punto cada uno de los temas que están en esta sección. La idea es comprender bien los conceptos para que siempre nos suenen y saber siempre, de donde viene, que cosa.
  • 3. Continuación del proyecto Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 4. • ¿Qué necesitamos? Lo primero es descargar nuestro proyecto desde GitHub. Creamos un directorio de trabajo, entramos dentro y en la terminal ejecutamos: # clonar https://github.com/jg...74/02...es.git/ Entramos dentro del directorio y abrimos VSC # code . En VSC deberíamos de ver algo tal que así ––––> Nota: La idea es tener nuestro código en GitHub, bien ordenado, documentado y listo para mostrar a quien tenga interés. No olvidemos que GitHub y LindIn, son nuestro porfolio. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Continuación del proyecto
  • 5. • ¿Qué necesitamos? A continuación, construimos nuestro proyecto gracias a los paquetes: - package.json, - Package.lock.json # npm install Por último, levantamos el servidor: # ng serve En resumen, estos son los pasos que hay que realizar para probar cualquier proyecto Angular que encontremos en GitHub o en cualquier otro repositorio.: - Clonar - Reconstruir - Servir Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Continuación del proyecto
  • 6. Módulo DBZ (Dragon Ball Z) Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 7. • ¿Qué necesitamos? Comenzamos creando el módulo ’dbz’ ç ¿Recuerdas como se crea un módulo? Dentro de la carpeta del proyecto escribimos lo siguiente en la terminal: # ng g m dbz Consultar la hoja de Atajos: Comandos para generar componentes... Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Continuación del proyecto
  • 8. • ¿Qué observamos? Tenemos: - Definición de la clase módulo, - Decorador de la clase módulo, - Importaciones de los módulos que necesitamos; NgModule, CommonModule Nota. En este caso CommonModule, no es necesario. A continuación creamos los siguientes directorios dentro de ‘dbz’: - components, vistos en la Sección 4, para guardar los pequeños componentes de ‘dbz’ - interfaces, que son muy parecidas a las de TS - pages, no es más que un componente, que agrupa componentes (páginas de navegación) - services, (todavía no sé que son… ya lo veremos) Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Continuación del proyecto
  • 9. • ¿Qué observamos? Dentro de ‘pages’ creamos el archivo ‘main-page.component.ts’. ¿Recuerdas como se crea un componente? Dentro del archivo comenzamos a escribir a-com… y pulsamos Tab o Enter. En el código del esqueleto del componente modificamos lo siguiente: Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Continuación del proyecto
  • 10. • TAREA Debemos aplicar los cambios necesarios para usar el componente, ‘main-page’ Pensemos lo que debemos tener en cuenta: - ¿Hemos declarado y exportado el componente ‘MainPageComponent’ en ‘dbz.module.ts’? - ¿Hemos importado el módulo ‘DbzModule’ en ‘app.module.ts’ - Por último, y no menos importante, ¿estamos usando el selector ‘app-dbz-main-page’ en ‘app.component.html’? Digamos que hemos recorrido las dependencias desde dentro hacia fuera. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Continuación del proyecto
  • 11. • TAREA Visualmente sería algo así (desde dentro hacia fuera): Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Continuación del proyecto app.module.ts import { … } from ‘./…’; imports: […] app.component.html <…></…> <hr> <app-counter></app-counter> <hr> <app-heroes-hero></app-heroes-hero> <hr> <app-heroes-list></app-heroes-list> dbz.module.ts import { … } from ‘./…’; declarations: […], exports: […] main-page-component.ts selector: ‘…’ templeUrl: ‘./…’
  • 12. • SOLUCIÓN Visualmente sería algo así (desde dentro hacia fuera): Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Continuación del proyecto app.module.ts import { … } from ‘./…’; imports: [DbzModule] app.component.html <app-dbz-main-page></app-dbz-main-page> <hr> <app-counter></app-counter> <hr> <app-heroes-hero></app-heroes-hero> <hr> <app-heroes-list></app-heroes-list> dbz.module.ts import { … } from ‘./…’; declarations: [MainPageComponent], exports: [MainPageComponent] main-page-component.ts selector: ‘…’ templeUrl: ‘./…’
  • 13. • ¿Qué observamos? El componente de DBZ no es un ‘stand-alone-component module’ así que tenemos que declararlo y exportarlo para que pueda ser usado. Se importa el módulo del cuál depende el componente DBZ, para poder hacer uso de él en la aplicación. Haciendo esto último simplificamos las dependencias de nuestra aplicación, porque para los sucesivos componentes que declaremos en el módulo, estos ya quedaran importados y listos para ser usados. Por favor, pensad en Angular como la evolución que hubo desde la arquitectura clásica (estilo romano) (dondé los muros soportaban la carga del techo), a la Gótica (dónde la carga la soportaban los pilares) En el primero las ventanas eran pequeñas, en el segundo se posibilitó la creación de esas vidrieras tan grandes y coloridas. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Continuación del proyecto
  • 14. Diseño de la pantalla Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 15. • TAREA Diseñar la pantalla para nuestra aplicación: Dragon Ball Z ¿Serían capaces de crear algo así? Escribimos el siguiente código en ‘main-page.component.html’: siguiente diapositiva… Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Diseño de la pantalla
  • 16. • SOLUCIÓN Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Diseño de la pantalla
  • 17. Pensemos en componentes pequeños Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 18. • ¿Qué necesitamos? Necesitamos empequeñecer el código anterior, debemos sintetizarlo de tal modo que la función resultante del componente, podamos reutilizarla en otro lugar. Ejemplo: Mandar los datos necesarios a un componente ‘lista’. Comencemos creando un componente de ‘lista de personajes’. Recordemos las dos formas que hemos aprendido para crear un componente: - Desde (CLI): # ng g c <…> - Manualmente: creamos el archivo ‘<…>component.ts’ y dentro del archivo añadimos el código escribiendo ‘a-compone + Tab’ Aprendamos una tercera forma. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Pensemos en componentes pequeños
  • 19. • ¿Qué necesitamos? 1 2 Nombre del componente: ‘list’ 3 Default component 4 Confirm 5 Debemos tener algo tal que así: Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Pensemos en componentes pequeños
  • 20. • ¿Qué necesitamos? Pasos: 1.- Añadimos dbz… al nombre del selector, ‘dbz-list’ Esto hace que el componente tenga más sentido en nuestra aplicación. 2.- Comprobamos que el componente ‘ListComponent’ está declarado en ‘dbz.module.ts’ y podemos hacer uso de este en ‘main-page-component.ts’ 3.- En ‘main-page-component.ts’ sustituimos el código del listado por: <dbz-list></dbz-list> 4.- Pegamos el código del listado en ‘list-component.html’ Si todo está correcto, nada debió de cambiar en el navegador, pero… ahora podemos hacer uso de esa lista de personajes en cualquier otro lugar. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Pensemos en componentes pequeños
  • 21. • TAREA Crear el componente ‘add-carácter’ para la parte del código del formulario. Sigue los pasos realizados para el componente lista. Recuerda añadir dbz… al nombre del selector una vez creado. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Pensemos en componentes pequeños
  • 22. • SOLUCIÓN 1 2 3 4 Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Pensemos en componentes pequeños
  • 23. @Input() Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 24. • ¿Qué necesitamos? Un decorador de componentes que permite la comunicación entre padre e hijo. Permite que un componente padre, ‘main-page.component.ts’ envie información a sus componentes hijos: ‘list.component.ts’, ‘add-character.component.ts’, etc… Definimos el decorador @Input() en el componente ‘list.component.ts’ para que muestre los datos de personajes que le proporcionará ‘main-page.component.ts’ La idea es que la página principal envie los datos que quiera mostrar a los diferentes componentes que la implementen. Archivos involucrados: main-page.component.ts/html =>(datos)=> list.componet.ts/html + interfaz(Character) Escribimos el siguiente código en los archivos correspondientes: siguiente diapositiva… Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Input()
  • 25. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Input() Uso del Decorador @Input() para la comunicación de datos desde el componente padre, al componente hijo character.interface.ts export interface Character { name: String; power: number; } main-page.component.ts import { Character } from '../interfaces/character.interface’; … export class MainPageComponent { public characters: Character [] =[{ name: 'Krillin’, power: 1000 },{ name: 'Goku’, power: 9500 },{ name: 'Vegeta’, power: 7500 }]; } list.component.ts import { Component, Input } from '@angular/core’; import { Character } from '../../interfaces/character.interface'; … export class ListComponent { @Input() // No olvidar importar el decorador Input public characterList: Character[] = [{ name: 'Trunks’, power: 10 }] } main-page.component.html <dbz-list [characterList]="characters"></dbz-list> list.component.html … <li *ngFor="let character of characterList" class="list-group-item"> <strong>name: </strong> <span>{{character.name}}</span> - <strong>Power: </strong> <span>{{character.power}}</span> </li> … 1 2 3 El tipo Character está definido por esta interfaz [characterList]="characters” e @Input() hacen posible la comunicación
  • 26. • ¿Qué observamos? Veamos una representación gráfica de lo que ocurre. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Input() main-page.component.html/ts list.component.html/ts .html … <li *ngFor="let character of characterList" class="list-group-item"> .ts import { …, Input } from '@angular/core'; import { Character } from '../../interfaces/character.interface'; … export class ListComponent { @Input() // No olvidar importar el decorador Input public characterList: Character[] = [{ … .html <dbz-list [characterList]="characters"></dbz-list> .ts import { Character } from '../interfaces/character.interface’; … export class MainPageComponent { public characters: Character [] =[{ …
  • 27. • ¿Qué observamos? De la misma forma que la interpolación, permiten la comunicación entre los archivos : - list.component.ts - *ngFor="let character of characterList" - <strong>name: </strong> <span>{{character.name}}</span> - list.component.html - public characterList: Character[] = [{ name: 'Trunks’, El Decorador, permite la comunicación entre los archivos. - list.component.ts - @Input() - public characterList: Character[] = [{ - main-page.component.html - <dbz-list [characterList]="characters"></dbz-list> Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Input()
  • 28. Expandiendo *ngFor Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 29. • ¿Qué necesitamos? La directiva ‘ngFor()’ nos ayuda a crear esos elementos HTML que se repiten en tiempo de ejecución, pero… ¿Tiene ‘ngFor()’ algún índice que podemos usar para referenciar dichos elementos? Estos son los principales: index, first, last, eve, odd… Escribimos el siguiente código en los archivos correspondientes: siguiente diapositiva… El siguiente Recurso muestra las variantes de diseño de listas en Bootstrap. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Expandiendo *ngFor()
  • 30. • ¿Qué necesitamos? list.component.html <li *ngFor="let character of characterList; let i=index; let isFirst = first; let isLast = last; let isEven = even; let isOdd = odd; "class="list-group-item"> <span class="text-primary">{{i}}. </span> <strong>Name: </strong> <span>{{character.name}}</span> - <strong>Power: </strong> <span>{{character.power}}</span><br /> <span>Es el primero: {{isFirst}}</span><br /> <span>Es par: {{isEven}}</span><br /> <span>Es impar:{{isOdd}}</span><br /> <span>Es el último: {{isLast}}</span> </li> Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Expandiendo *ngFor()
  • 31. ngClass – Clases basado en condiciones Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 32. • ¿Qué necesitamos? Es normal que en tiempo de ejecución queramos que los objetos se presenten de un modo u otro, e incluso que los datos del mismo objeto, tengan representaciones diferentes. A continuación dos técnicas para cambiar la visualización de los datos: Escribimos el siguiente código en el archivo ‘list.component.html’: siguiente diapositiva… Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – ngClass – Clases (basado en condiciones)
  • 33. • ¿Qué necesitamos? TÉCNICA 1 Hacemos uso de las clases <h4>Listado</h4> <ul class="list-group"> <li *ngFor="let character of characterList; let i=index; let isFirst = first; let isLast = last; let isEven = even; let isOdd = odd;" class="list-group-item {{ isFirst?'list-group-item-success’: isEven?'list-group-item-primary’: isLast?'list-group-item-dark’:’’ }}"> <span class="text-primary">{{i+1}}. </span> <strong>Name: </strong> <span>{{character.name}}</span> - <strong>Power: </strong> <span>{{character.power}}</span> </li> </ul> Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – ngClass – Clases (basado en condiciones)
  • 34. • ¿Qué necesitamos? TÉCNICA 2 Hacemos uso de la directiva ‘ngClass’ <h4>Listado</h4> <ul class="list-group"> <li *ngFor="let character of characterList; let i=index; let isFirst = first; let isLast = last; let isEven = even; let isOdd = odd;" class="list-group-item" [ngClass]="{ 'list-group-item-success': isFirst, 'list-group-item-primary': isEven, 'list-group-item-dark': isLast }"> <span class="text-primary">{{i+1}}. </span> <strong>Name: </strong> <span>{{character.name}}</span> - <strong>Power: </strong> <span>{{character.power}}</span> </li> </ul> Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – ngClass – Clases (basado en condiciones)
  • 35. • ¿Qué observamos? Angular nos ayuda a simplificar la lógica de programación. La estructuración del código clarifica el código. Es verdad que tenemos que adaptarnos a un nivel de abstracción: - aprender dónde está cada cosa, - como son las relaciones entre los diferentes objetos, - herramientas del lenguaje, etc… pero todo es para un propósito mayor: - el código es más escalable, - la programación en equipo se simplifica, - hay un mayor control sobre lo que se programa (todo se verifica al momento) Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – ngClass – Clases (basado en condiciones)
  • 36. FormsModule y ngModel Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 37. • ¿Qué necesitamos? Comencemos a trabajar con formularios. Sintaxis (one-way data-binding): - (click), esperamos el suceso de eventos Ejemplo: (click)="increaseBy(1)" - [value], hacemos uso de los atributos Ejemplo: [value]="character.name" Consultar la hoja de Atajos: FormsModule de @angular/forms Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – FormsModule y ngModel
  • 38. • ¿Qué necesitamos? Sintaxis (two-way data-binding): - [(ngModel)], con esta directiva conseguimos: - escuchar el evento de cambio/acción sobre el objeto que se aplica. - cambiar los valores del código que programa el objeto que mostramos. Ejemplo: [(ngModel)]="character.name" Escribimos el siguiente código en los archivos: - ‘add-cha.component.html/ts’, - ‘dbz.module.ts’ siguiente diapositiva… Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – FormsModule y ngModel
  • 39. • ¿Qué necesitamos? Muy importante, no olvidar importar el módulo para la gestión de formularios. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – FormsModule y ngModel
  • 40. • ¿Qué necesitamos? Muy importante, usar el intellisense para que automáticamente haga el ‘import’ Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – FormsModule y ngModel
  • 41. • ¿Qué observamos? Error. Dos formas de resolverlo: - Este error nos indica que hemos olvidado el atributo que los inputs suelen llevar a la hora de formar parte de un formulario. - De no querer hacerlo así tendremos que definir el formulario como un stand-alone.component. Este se debe a que Angular intenta por todos los medios controlar todos y cada uno de los objetos con los que tratamos, ya sea bien en el .ts (con el control de tipos) o bien en el .html (gestionando las referencias de los mismos, así como los valores que poseen) - Añadimos el atributo ’name’ a las etiquetas ‘input’ - Ahora sí vemos como el formulario muestra el contenido del atributo ‘character’ El error desaparece. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – FormsModule y ngModel
  • 42. • ¿Qué necesitamos? add-character.component.html add-character.component.ts Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – FormsModule y ngModel
  • 43. • ¿Qué observamos? La directiva ‘ngModel’ muestra los valores del atributo ‘character’ gracias a los atributos que hemos añadido en las etiqueta input (one-way binding) Cuando modificamos los valores estos se modifican automáticamente en el atributo ‘character’ (two-way binding), tal y como se puede comprobar con el método ‘emitCharacter()’ que hemos implementado. Cuando pulsamos en el botón ‘Agregar’ ya no se produce el refresco propio de los formularios con ‘submit’ El evento ‘click’ hace que el botón cumpla su función pero no es ese el lugar correcto para colocarlo, dado que estamos trabajando con un formulario. Lo correcto es capturar el evento en el propio formulario. (En el próximo apartado lo modificaremos) Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – FormsModule y ngModel
  • 44. @Output() Emitir eventos al padre Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 45. • ¿Qué necesitamos? Un decorador de componentes que permite la comunicación entre hijo y padre. Permite que un componente hijo, ‘add-character.component.ts’ envie información a su componente padre: ‘main-page.component.ts’ Definimos el decorador @Output() en el componente ‘add-character.component.ts’ para que emita un evento, producto de haber agregado un nuevo personaje, que enviará a ‘main-page.component.ts’ La idea es que la página principal reciba el nuevo dato que hemos introducido en el componente. Archivos involucrados: add-character.component.ts/html =>(evento+datos)=> main-page.componet.ts/html Escribimos el siguiente código en los archivos correspondientes: siguiente diapositiva… Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Output() Emitir eventos al padre
  • 46. • ¿Qué necesitamos? Comencemos cambiando el evento del botón. Podríamos poner en el ‘form’ algo tal que así: <form class="row" (click)="emitCharacter()"> Pero… aprendamos una nueva directiva: ‘ngSubmit’ <form class="row" (ngSubmit)="emitCharacter()"> También, evita que se recargue la página. Por último, limpiamos el formulario en el método ‘emitCharacter()’ emitCharacter():void { console.log(this.character); this.character.name=’’; this.character.power=0; } Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Output() Emitir eventos al padre
  • 47. • ¿Qué necesitamos? Trabajemos ahora con el decorador @Output() Básicamente se trata de una función que le permitirá al padre atender los eventos del hijo. En nuestro ejemplo: - Si agregamos un personaje (add-character.component.html/ts) [hijo], - Se actualiza la página principal (main-page.component.html/ts) [padre] Una vez se actualiza la página principal Angular propagará los cambios automáticamente para que el ‘list.component.html/ts’ muestre correctamente los datos. Consultar la hoja de Atajos: @Output y RxJS (subscripciones) Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Output() Emitir eventos al padre
  • 48. • ¿Qué necesitamos? Creamos un objeto que va a - emitir el personaje nuevo que hemos añadido en el componente ‘add-character.component.ts’ [hijo], - enviándolo al componente ‘main-page.component.ts’ [padre] Para eso hacemos uso de la clase ‘EventEmitter’, su método ‘.emit’ y del decorador ‘@Output()’ Escribimos el siguiente código en los archivos: - ‘add-character.component.html/ts’, - ‘main-page.component.html/ts’ siguiente diapositiva… Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Output() Emitir eventos al padre
  • 49. • ¿Qué necesitamos? add-character.component.ts import { Component, EventEmitter, Output } from '@angular/core’; … export class AddCharacterComponent { @Output() public onNewCharacter:EventEmitter<Character> = new EventEmitter(); … emitCharacter():void { … this.onNewCharacter.emit(this.character); Por favor, no olvidéis de hacer uso del intellisense, este añadirá automáticamente la clase al ‘import’ Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Output() Emitir eventos al padre
  • 50. • ¿Qué necesitamos? Ahora necesitamos recibir dicho personaje en nuestra página principal Creamos un método que va a - recibir el personaje nuevo que hemos añadido en el componente ‘add-character.component.ts’ [hijo], - usandolo en el componente ‘main-page.component.ts’ [padre] Y… ¿cómo recibo el valor de ‘character’ en el método que uso en el .html? Para eso hacemos uso de ‘$event’ $event, al igual que en JavaScript, es un evento global, propio de los eventos, que que forma parte del lenguaje TS y del que siempre podemos disponer, aún sin haberlo creado. Contiene absolutamente toda la información referente al evento, quien lo originó, cuando, dónde, circunstancias… Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Output() Emitir eventos al padre
  • 51. • ¿Qué necesitamos? main-page.component.html <dbz-add-character (onNewCharacter)="onNewCharacter($event)"></dbz-add-character> main-page.component.ts onNewCharacter(character: Character): void { console.log("MainPage"); console.log("character"); } Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Output() Emitir eventos al padre
  • 52. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Output() Emitir eventos al padre Uso del Decorador @Output() para la emisión eventos y datos desde el componente hijo, al componente padre add-character.component.ts import { …, EventEmitter, Output } from '@angular/core’; … export class AddCharacterComponent { @Output() public onNewCharacter:EventEmitter<Character> = new EventEmitter(); … emitCharacter():void { … this.onNewCharacter.emit(this.character); … main-page.component.ts … onNewCharacter(character: Character): void { console.log("MainPage"); console.log("character"); } add-character.component.html … <form class="row" (ngSubmit)="emitCharacter()"> main-page.component.html … <dbz-add-character (onNewCharacter)="onNewCharacter($event)"></dbz-add- character>
  • 53. • ¿Qué observamos? Veamos una representación gráfica de lo que ocurre. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – @Output() Emitir eventos al padre main-page.component.html/ts add-character.component.html/ts .ts import { Component, EventEmitter, Output } from '@angular/core’; … export class AddCharacterComponent { @Output() public onNewCharacter:EventEmitter<Character> = new EventEmitter(); … emitCharacter():void { … this.onNewCharacter.emit(this.character); … .html … <dbz-add-character (onNewCharacter)="onNewCharacter($event)"></dbz-add- character> .ts … onNewCharacter(character: Character): void { console.log("MainPage"); console.log("character"); }
  • 54. Formas de depurar la app Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 55. • ¿Qué necesitamos? 1.- Devtools de Angular Las herramientas de desarrollo de React y Vue están más logradas pero Angular tiene un Framework mucho más elaborado. Es cuestión de tiempo que Angular mejore ese aspecto. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Formas de depurar la app
  • 56. • ¿Qué necesitamos? 2.- debugger; Con esta instrucción paramos la ejecución/interpretación del código y posicionándonos encima de los objetos podremos ver los valores. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Formas de depurar la app
  • 57. • ¿Qué observamos? 3.- breakpoints En la misma interfaz, podemos establecer puntos de interrupción para ir paso a paso y ver el estado de los objetos. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Formas de depurar la app
  • 58. Añadir personaje al listado Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 59. • ¿Qué necesitamos? Tan simple como esto: onNewCharacter(character: Character): void { this.characters.push(character); } Como se comentó, Angular propagará dicho valor entre los diferentes componentes que hagan uso del mismo. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Añadir personaje al listado
  • 60. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Añadir personaje al listado Uso del Decorador @Output() para la emisión eventos y datos desde el componente hijo, al componente padre add-character.component.ts import { …, EventEmitter, Output } from '@angular/core’; … export class AddCharacterComponent { @Output() public onNewCharacter:EventEmitter<Character> = new EventEmitter(); … emitCharacter():void { … this.onNewCharacter.emit(this.character); … main-page.component.ts … onNewCharacter(character: Character): void { this.characters.push(character); } add-character.component.html … <form class="row" (ngSubmit)="emitCharacter()"> main-page.component.html … <dbz-add-character (onNewCharacter)="onNewCharacter($event)"></dbz-add- character>
  • 61. • ¿Qué observamos? Veamos una representación gráfica de lo que ocurre. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Añadir personaje al listado main-page.component.html/ts add-character.component.html/ts .html (ngSubmit)="emitCharacter()” .ts import { Component, EventEmitter, Output } from '@angular/core’; … export class AddCharacterComponent { @Output() public onNewCharacter:EventEmitter<Character> = new EventEmitter(); … emitCharacter():void { … this.onNewCharacter.emit(this.character); … .html … <dbz-list [characterList]="characters" (onDeleteIndex)="onDeleteIndex($event)"></dbz-list> .ts … onNewCharacter(character: Character): void { this.characters.push(character); }
  • 62. • ¿Qué necesitamos? Hemos añadido elementos a la lista. ¿Qué tal si los borramos? Añadimos el botón de eliminar a cada componente: El siguiente Recurso muestra el uso del método ‘.splice()’ de arrays. Eliminar elementos de una lista. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Eliminar personaje del listado
  • 63. • TAREA Emitir el índice del personaje sobre el cual se ha pulsado el botón eliminar en el componente, ‘list.component.html/ts’ Recordemos lo que hicimos al emitir el ‘character’ que queríamos insertar: - capturar el evento, ‘list.component.html’ y <button (click)="emitIndex(i)" - manejarlo con el método ‘emitIndex(i)’, ‘list.component.ts’ @Output() public onDeleteIndex:EventEmitter<number> = new EventEmitter(); emitIndex(index: number): void { this.onDeleteIndex.emit(index); } Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Eliminar personaje del listado
  • 64. • SOLUCIÓN list.component.html … <button (click)=”emitIndex(i)" class="btn btn-danger">X</button> </li> list.component.ts … emitIndex(index: number): void { console.log({index}); } Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Eliminar personaje del listado
  • 65. • TAREA Ahora que tenemos el índice del elemento que queremos borrar debemos emitirlo a través de un evento de Emisión, para que: - el componente ‘main-page.component.ts’ lo capture, y - a través de un método ‘onDeleteIndex(index)’ borre el personaje. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Eliminar personaje del listado
  • 66. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Añadir personaje al listado Uso del Decorador @Output() para la emisión eventos y datos desde el componente hijo, al componente padre list.component.ts import { …, EventEmitter, Output } from '@angular/core’; … @Output() public onDeleteIndex:EventEmitter<number> = new EventEmitter(); emitIndex(index: number): void { this.onDeleteIndex.emit(index); } … main-page.component.ts … onDeleteIndex(index: number): void { this.characters.splice(index, 1); } list.component.html … <button (click)="emitIndex(i)" main-page.component.html … <dbz-list [characterList]="characters” (onDeleteIndex)="onDeleteIndex($event)></dbz-list>
  • 67. • SOLUCIÓN (ELIMINAR) Veamos una representación gráfica de lo que tenemos que hacer al borrar. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Eliminar personaje del listado main-page.component.html/ts list.component.html/ts .html (ngSubmit)="emitIndex()” .ts import {… EventEmitter, Output } @Output() public onDeleteIndex:EventEmitter<number> = new EventEmitter(); emitIndex(index: number):void { this.onDeleteCharacter.emit(this.character); } .html <dbz-list [characterList]="characters” (onDeleteIndex)="onDeleteIndex($event)></dbz-list> .ts onDeleteIndex(index: number): void { this.characters.splice(index, 1); }
  • 68. Servicios Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 69. • ¿Qué observamos? Hasta ahora hemos definido nuestros datos de personajes: en ‘main-page.component.ts’, pero este no es el mejor sitio para hacerlo, tampoco es correcto que tengamos nuestra lógica para editarlos, ya que puede que en otro componente (otras páginas, del mismo nivel, ‘hermanos’) necesiten dicha información, y compartir dicha información a ese nivel, es complicado. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Servicios Personajes public characters: Character[] = [{ name: 'Krillin', power: 75_000 }, { name: 'Gohan', power: 1_950_000 }, { name: 'Piccolo', power: 1_200_000 }, { name: 'Goku', power: 150_000_000 }, { name: 'Vegeta', power: 3_000_000 }, { name: 'Frieza', power: 120_000_000 },];
  • 70. • ¿Qué necesitamos? Para garantizar que los datos con los que trabajamos están encapsulados, son de única instanciación y disponibles a todos los niveles usaremos los servicios Singleton. Los servicios Singleton en Angular se maneja mediante Inyección de dependencias (DI, en inglés) Y, ¿que es esto de la (DI)? Pues, un patrón de diseño en el que se garantiza que los constructores de las clases reciben los objetos ya instanciados, con lo que se garantiza la composición en vez de la herencia. El siguiente Recurso muestra el uso de los servicios Singleton. Es decir, que una clase solo tengan una única instancia. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Servicios
  • 71. • ¿Qué necesitamos? Ejemplo: Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Servicios Sin Inyección de dependencias Con Inyección de dependencias class Article{ constructor(){ this.user = new User(); // instancia this.image = new Image(); // instancia } } /* No es correcto que el constructor de la clase Article se tenga que encargar de instanciar los elementos que la constituyen: User e Image Podemos hablar entonces de acoplamiento, si queremos usar la Image en otros objetos no podríamos hacerlo */ class Article{ constructor(private user : User, private image: Image){} } /* Recuerda: esta es la definición corta de clase */ /* La definición tradicional sería esta: */ class Article{ private user : User; private image : Image constructor(user : User, image : Image){ this.image = image; this.user = user; } } new Article(new User(), new Image()); // instancias Fuente: https://codigofacilito.com/articulos/angular-di
  • 72. • ¿Qué necesitamos? Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Servicios Con Inyección de dependencias @NgModule({ providers: [User] }) @Component({}) class Ejemplo{ // En este ejemp. User es el injector token constructor(private user : User){} }
  • 73. • ¿Qué necesitamos? Creamos el servicio: - CLI, en línea de comando - Angular schematic, botón derecho en carpeta ‘service’, pulsar: ‘Angular: Generate service’ - A mano, creando los archivos: .html, .ts, etc… Hagámoslo a mano: Creamos el archivo: ‘dbz.services’ Escribimos el siguiente código en los archivos correspondientes: siguiente diapositiva… Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Servicios
  • 74. • ¿Qué necesitamos? dbz.service.ts Escribimos: a-ser… y vemos como aparecen todos los componentes disponibles. Elejimos: a-service y automáticamente nos escribe: import { Injectable } from '@angular/core'; @Injectable({providedIn: 'root’}) export class ServiceNameService { constructor() { } } Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Servicios
  • 75. • ¿Qué necesitamos? Como hasta ahora, con cualquier componente, un servicio es una clase. @Inyectable, le dirá a angular que trate a la clase como un servicio. Todos los servicios en Angular, desde la versión 6, implementan ‘providedIn: ‘root’ Sin o lo tuviera tendríamos que definirlo en la parte de los ‘providers’ en el archivo ‘app.module.ts’ Con esto, Angular define al servicio con un ‘Singleton’ en todo el proyecto. Es decir, no importa dónde yo use ese servicio que, siempre que solicite el valor de la instancia, mediante Inyección de dependencias, obtendré los mismos datos, el mismo contenido, los mismos valores. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Servicios
  • 76. • ¿Qué necesitamos? Modificamos el siguiente fichero: dbz.service.ts import { Injectable } from '@angular/core'; import { Character } from '../interfaces/character.interface'; @Injectable({ providedIn: 'root' }) export class DbzService { public characters: Character[] = [{ name: 'Krillin’, power: 75_000 }… Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Servicios Sí, nos hemos traído todo el contenido de la clase en: ‘main-page.component.ts’ y lo hemos pegado en la clase del servicio ‘dbz.service.ts’
  • 77. • ¿Qué necesitamos? Modificamos el siguiente fichero: main-page.component.ts import { Component } from '@angular/core'; import { Character } from '../interfaces/character.interface'; import { DbzService } from '../services/dbz.sevice’; @Component({ selector: 'app-dbz-main-page', templateUrl: './main-page.component.html' }) export class MainPageComponent { constructor(public dbzService: DbzService) { } } Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Servicios
  • 78. • ¿Qué necesitamos? Modificamos el siguiente fichero: main-page.component.ts <dbz-list [characterList]="dbzService.characters" (onDeleteIndex)="dbzService.onDeleteIndex($event)"></dbz-list> </div> <div class="col"> <dbz-add-character (onNewCharacter)="dbzService.onNewCharacter($event)"></dbz-add-character> </div> … Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Servicios
  • 79. Paquetes externos uuID Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 80. • ¿Qué observamos? Recordemos que seguimos con el problema de borrar los elementos de la lista en base al índice que ocupan en el array (o índice de cualquier objeto que lo implemente) Los id’s deben de ser únicos para cada personaje. Si la implementación es correcta, los id’s únicos deben ser algo que quede a cargo de algún paquete de instalación del proyecto, así nos eximimos de la responsabilidad de tener colisiones a la hora de identificar a los elementos. El siguiente Recurso es un paquete para Angular que nos ayuda a generar id’s únicos con cierto formato. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 81. • ¿Qué observamos? Para Angular existe un paquete que nos ayuda a crear id únicos: ‘uuid’ Instalémoslo: # npm i uuid Usémoslo importándolo en el servicio ‘dbz.service.ts’: import { } from 'uuid’; Vemos que se produce un error por dependencias Resolvámoslo instalando la dependencia que se nos indica en el error: # npm i --save-dev @types/uuid Ahora sí podemos usarlo correctamente en la importación: import { v4 as uuid } from 'uuid’; v4 as uuid, utiliza el generador ‘v4’ de id’s únicos con el álias ‘uuid’ Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 82. • ¿Qué necesitamos? Agreguemos un id único al objeto ‘Character’. ¿Recordáis dónde está implementado el tipo de dicho objeto ‘Character’? Sí, en la interfaz ‘character.interface.ts’: export interface Character { id?: string; name: String; power: number; } Ya que no vamos a proceder a refactorizar toda la aplicación, lo dejamos como opcional para no tener que cambiar todo el código… por ahora  Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 83. • ¿Qué necesitamos? ‘dbz.service.ts’ import { v4 as uuid } from 'uuid'; import { Character } from '../interfaces/character.interface'; @Injectable({ providedIn: 'root' }) export class DbzService { public characters: Character[] = [{ id: uuid(), name: 'Krillin’, … Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 84. • TAREA En el servicio ‘dbz.service.ts’ implementamos el método ‘onDeleteId(id: string)’ con el siguiente código: onDeleteId(id: string): void { this.characters = this.characters.filter(character => character.id != id); } Vemos que nuestra aplicación ha dejado de funcionar. Las tareas son: 1.- Arreglar los errores producto del la implementación del nuevo método. 2.- Hacer que el id sea obligatorio y no opcional. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 85. • SOLUCIÓN 1.- Arreglar los errores producto del la implementación del nuevo método. ’main-page.component.html’ <dbz-list [characterList]="dbzService.characters" (onDeleteId)="dbzService.onDeleteId($event)"></dbz-list> </div> … ’main-page.component.ts’ Eliminamos el ‘import { Character }…’ El objeto ya no se usa en este componente. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 86. • SOLUCIÓN 2.- Hacer que el id sea obligatorio y no opcional. ‘dbz.service.ts’ onNewCharacter(character: Character): void { // const newCharacter: Character = { id: uuid(), ...character } // operador 'spread’ this.characters.push(character); } // const newCharacter… Se usó cuándo no teníamos implementado el ‘id’ en ‘add-character.component.ts’ public character: Character = { id: uuid(), name: 'Videl’, power: 14_000 } Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 87. • SOLUCIÓN 2.- Hacer que el id sea obligatorio y no opcional. ‘list.component.html’ … <button (click)="emitId(character.id)" class="btn btn-danger">X</button> </li> Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID ‘list.component.ts’ export class ListComponent { @Output() public onDeleteId:EventEmitter<string> = new EventEmitter(); emitId(id: string): void { this.onDeleteId.emit(id); }
  • 88. Servicio Privado Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 89. • ¿Qué observamos? Malas prácticas. Recordemos que al implementar nuestro servicio, toda la lógica de control sobre el listado de personajes, ‘main-page.component.ts’, migró a la clase de dicho servicio, ‘dbz.service.ts’ En nuestro ‘main-page.component.ts’ solo quedó el constructor que instancia dicho servicio mediante Inyección de dependencias. export class MainPageComponent { constructor(public dbzService: DbzService) { } … Este servicio se construyo como público y las buenas prácticas aconsejan que sea privado, lo cuál implica que ya no tengo acceso al mismo desde ’main-page.componente.html’ o cualquier otro componente que lo importe. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 90. • ¿Qué observamos? Buenas prácticas. export class MainPageComponent { constructor(private dbzService: DbzService) { } … Para hacer esto posible debemos crear métodos en la clase que sirvan de puente para comunicarme con el servicio. Escribimos el siguiente código en los archivos correspondientes: siguiente diapositiva… Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 91. • ¿Qué necesitamos? ‘main-page.component.html’ … (onDeleteId)="onDeleteId($event)"></dbz-list> </div> <div class="col"> <dbz-add-character (onNewCharacter)="onNewCharacter($event)"></dbz-add-character> </div> Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 92. • ¿Qué necesitamos? ‘main-page.component.ts’ onNewCharacter(character: Character) { this.dbzService.addCharacter(character); // refactorizo } onDeleteId(id: string): void { this.dbzService.deleteCharacter(id); // refactorizo } Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 93. • ¿Qué necesitamos? ‘dbz.service.ts’ addCharacter(character: Character): void { this.characters.push(character); } deleteCharacter(id: string): void { this.characters = this.characters.filter(character => character.id != id); } Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 94. • TAREA (extra) En esta aplicación de Dragón Ball Z hemos implementado: - El mostrar los personajes (Listado), - La creación de personajes (botón ‘Agregar’), y - La eliminación de personajes (botón ‘X’) La tarea consiste en implementar el botón ‘U’ (update), para modificar a un personaje. Angular 16+ Edición 2023 Sección 5 José García Angular 16+ Edición 2023 TS – Paquetes externos uuID
  • 95. Respaldo en Github Angular 16+ Edición 2023 Sección 4 José García Angular 16+ Edición 2023 TS – Nuevo apartado
  • 96. • ¿Qué necesitamos? Guardamos nuestro proyecto en GitHub. 1.- ¿Tenemos cuenta en github.com? - Si la tienes, recuerda el usuario y contraseña de tu cuenta. - Si no la tienes, crea una cuenta en github.com, recuerda tu usuario y contraseña. 2.- En la terminal (dentro del directorio del proyecto) ’03-expandir-angular-DBZ’): - # git init - # git add . - # git commit –m ‘Fin de la sección 4’ 3.- Accedemos a github.com 4.- Creamos el repositorio: ’03-expandir-angular’ Angular 16+ Edición 2023 Sección 4 José García Angular 16+ Edición 2023 TS – Respaldo en Github
  • 97. • ¿Qué necesitamos? 5.- Copiamos las instrucciones para: ‘push an existing repository from the command line’ 6.- Volvemos a la terminal y aplicamos las instrucciones anteriores: - # git remote add origin https://github.com/jgarmay674/03-expandir-angular.git - # git branch -M main - # git push -u origin main Error: remote: Support for password authentication was removed on August 13, 2021. remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote- repositories#cloning-with-https-urls for information on currently recommended modes of authentication. fatal: Authentication failed for ‘https://github.com/jgarmay674/02-angular-bases.git’ Angular 16+ Edición 2023 Sección 4 José García Angular 16+ Edición 2023 TS – Respaldo en Github
  • 98. • ¿Qué necesitamos? 7.- Creamos un token, Personal Access Token (PAT) 1 2 3 - Genera un nuevo token (classic) - Indica el uso del token y ‘No expiration’ - Pulsa el botón ‘Generar token’ Angular 16+ Edición 2023 Sección 4 José García Angular 16+ Edición 2023 TS – Respaldo en Github
  • 99. • ¿Qué necesitamos? 8.- Ahora sí podemos ejecutar: # git push -u origin main Solicitará la siguiente información: - Username (de github.com) - Password (pegamos el token) Guardar las credenciales: Creamos el archivo ‘.netrc’ en el raíz. Contenido: machine https://github.com/jg...74/02...es.git/ login jg…74 password ghp_NL…7c Angular 16+ Edición 2023 Sección 4 José García Angular 16+ Edición 2023 TS – Respaldo en Github