Herramientas de usuario

Herramientas del sitio


clase:daw:diw:1eval:tema03

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
clase:daw:diw:1eval:tema03 [2025/11/05 16:46] – Lorenzoclase:daw:diw:1eval:tema03 [2026/10/23 23:04] (actual) – Reorganización del módulo: contenido movido a las páginas nuevas de clase:daw:diw claude
Línea 1: Línea 1:
-====== 3. Creación de componentes ====== 
-En este tema vamos a crear nuevo componentes de Angular 
- 
-===== Crear tu nuevo componente botón ===== 
-Vamos a crear nosotros un nuevo componente ''boton''. 
- 
- 
-Para ello vamos a crear los 3 ficheros que necesitas todo componente: 
-  * ''boton/boton.ts'': El código TypeScript que tiene la lógica del botón 
-  * ''boton/boton.html'': El HTML correspondiente al botón 
-  * ''boton/boton.scss'': Los estilos en SASS del botón. Por ahora es simplemente estilos CSS. 
- 
- 
-Los 3 ficheros los crearás dentro de la carpeta ''src/app/components/ui'' 
- 
-<sxh text;gutter:false> 
-src/ 
- └─ minecraft/ 
-     └─ components/             
-         ├─ ui/ 
-         │   ├─ boton/ 
-         │   │   ├─ boton.ts 
-         │   │   ├─ boton.html 
-         │   │   └─ boton.scss 
-         │   └─ panel/ 
-         └─ paginas/ 
-             ├─ minecraft-main/ 
-             │   ├─ minecraft-main.ts 
-             │   ├─ minecraft-main.html 
-             │   └─ minecraft-main.scss 
-             └─ productos/ 
-                 ├─ productos.ts 
-                 ├─ productos.html 
-                 └─ productos.scss 
-</sxh> 
- 
-El contenido de cada uno de ellos será: 
- 
- 
-<sxh typescript; title: boton.ts> 
-import { Component  } from '@angular/core'; 
-import {CommonModule} from '@angular/common'; 
- 
-@Component({ 
-  selector: 'boton', 
-  imports: [CommonModule], 
-  templateUrl: './boton.html', 
-  styleUrl: './boton.scss' 
-}) 
-export class Boton  { 
- 
-} 
-</sxh> 
- 
-La parte más importante es el objeto que se le pasa al decocador ''@Componente''. Veamos sus propiedades: 
-  * ''selector'': Es la etiqueta que usaremos cuando queramos usar el componente. ''<boton></boton>'' 
-  * ''imports'': Importamos otros componentes para poder usarlos dentro del HTML del componente. 
-  * ''templateUrl'': El nombre del fichero HTML 
-  * ''styleUrl'': El nombre del fichero SCSS de estilos 
- 
- 
-<sxh typescript; title: boton.html> 
-<button class="boton">Aceptar</button> 
-</sxh> 
- 
- 
-<sxh css; title: boton.scss> 
-.boton { 
-  font-family: sans-serif; 
-  font-size: 16px; 
-  padding: 6px; 
- 
-  border-radius: 6px; 
-  border-width: 1px; 
-  border-style: solid; 
- 
-  display: inline-block; 
-  cursor: pointer; 
-  text-decoration: none; 
- 
- 
-  border-color: #0056b8; 
-  background-color: #0056b8; 
-  color: #ffffff; 
-} 
-</sxh> 
- 
- 
- 
- 
- 
- 
- 
-===== Usando un componente ===== 
-Como ya hicimos en el tema anterior, hay que importarlo en el ''.ts'' donde quedamos usarlo y añadirlo al array de ''imports''.  
- 
-Primero lo importamos en el ''app.ts''. 
- 
- 
-Primero lo importamos en el ''app.ts''. 
- 
-<sxh typescript;highlight: [4,8]; title:app.ts;> 
-import { Component, signal } from '@angular/core'; 
-import { RouterOutlet } from '@angular/router'; 
-import {MatButtonModule} from '@angular/material/button'; 
-import { Boton } from './shared/ui/boton/boton'; 
-  
-@Component({ 
-  selector: 'app-root', 
-  imports: [RouterOutlet, MatButtonModule,Boton], 
-  templateUrl: './app.html', 
-  styleUrl: './app.scss' 
-}) 
-export class App { 
-  protected readonly title = signal('EjemploComponentesAngular'); 
-  
-  
-  
-} 
-</sxh> 
- 
-Y ahora ya podemos usar la etiquetya ''<boton></boton>'' en el ''app.html'' 
- 
-<sxh typescript;highlight: [13]; title:app.html;> 
-<style> 
-</style> 
-   
-<h1 >Hola mundo</h1> 
-   
-<button matButton="filled"> 
-  Aceptar 
-</button> 
- 
-<br> 
-<br> 
- 
-<boton></boton> 
-   
-<router-outlet /> 
-</sxh> 
- 
-===== Contenido de la etiqueta ===== 
-Nuestros botones es muy pobre porque no permite indicar el texto del botón. Para poder hacerlo simplemente hay que usar la etiqueta ''<ng-content></ng-content>'' en el ''boton.html'' 
- 
- 
-<sxh typescript;highlight: [2];  title: boton.html> 
-<button class="boton"> 
-  <ng-content></ng-content> 
-</button> 
-</sxh> 
- 
-Y ahora ya podremos cambiar el texto: 
- 
-<sxh typescript;highlight: [13]; title:app.html;> 
-<style> 
-</style> 
-   
-<h1 >Hola mundo</h1> 
-   
-<button matButton="filled"> 
-  Aceptar 
-</button> 
- 
-<br> 
-<br> 
- 
-<boton>Hola mundo</boton> 
-   
-<router-outlet /> 
-</sxh> 
- 
-===== Personalizar del componente ===== 
-Vamos ahora añadir atributos a nuestro componente para poder personalizarlo. Para ello vamos a añadir propiedades a la clase TypeScript del componente con el decorador ''Input()'' 
- 
- 
-Nuestro objetivo es poder hacer lo siguiente: 
-<sxh html> 
-<boton [backgroundColor]="'#FF0000'" [color]="'#00FF00'">Hola mundo</boton> 
-</sxh> 
- 
- 
-Lo primero es añadir las propiedades ''backgroundColor'' y ''color'' a la clase ''Boton''. 
- 
-<sxh typescript;highlight: [11,12]; title: boton.ts> 
-import { Component, Input } from '@angular/core'; 
-import {CommonModule} from '@angular/common'; 
- 
-@Component({ 
-  selector: 'boton', 
-  imports: [CommonModule], 
-  templateUrl: './boton.html', 
-  styleUrl: './boton.scss' 
-}) 
-export class Boton  { 
-  @Input() backgroundColor: string = '#0B5CD5'; 
-  @Input() color: string = '#F5F7FF'; 
-} 
-</sxh> 
- 
-Para usarlas en el ''boton.html'' hay 3 formas distintas: 
- 
-  * Directamente interpolando los valores: 
- 
-<sxh typescript;highlight: [1];  title: boton.html> 
-<button class="boton" style="color:{{color}};background-color:{{backgroundColor}}"> 
-  <ng-content></ng-content> 
-</button> 
-</sxh> 
- 
-  * Usando ''[style]'' de Angular: 
- 
-<sxh typescript;highlight: [1];  title: boton.html> 
-<button class="boton" [style.color]="color" [style.backgroundColor]="backgroundColor"> 
-  <ng-content></ng-content> 
-</button> 
-</sxh> 
- 
-  * Usando ''[ngStyle]'' de Angular: 
- 
-<sxh typescript;highlight: [1];  title: boton.html> 
-<button class="boton" [ngStyle]="{'color': color, 'background-color': backgroundColor}"> 
-  <ng-content></ng-content> 
-</button> 
-</sxh> 
- 
-  * Por último lo ideal siempre es usar clases CSS y evitar usar ''style'': 
- 
-<sxh typescript;highlight: [1];  title: boton.html> 
-<button class="boton" [ngClass]="[colorClass, backgroundClass]"> 
-  <ng-content></ng-content> 
-</button> 
-</sxh> 
- 
-<sxh typescript;highlight: [1];  title: boton.html> 
-<button class="boton color--{{color}} background--{{backgroundColor}}"> 
-  <ng-content></ng-content> 
-</button> 
-</sxh> 
- 
-<sxh typescript;highlight: [1];  title: boton.html> 
-<button class="boton" [ngClass]="['color--'+color, 'background--'+backgroundColor]"> 
-  <ng-content></ng-content> 
-</button> 
-</sxh> 
- 
-Pero en ese caso hay que limitar los posibles valores, definir las clases, relacionarlas con las propiedades TypeScript. Esto lo veremos en el siguiente apartado. 
- 
-===== Limitando los valores ===== 
-En el apartado anterior hemos visto como definir los colores de los botones pero como vimos en el primer tema, realmente hay únicamente unos valores de colores que puede haber 
- 
-{{:clase:daw:diw:1eval:primary.png|}} 
-{{:clase:daw:diw:1eval:alt-primary.png|}} 
-{{:clase:daw:diw:1eval:rojo-primary.png|}} 
- 
- 
-Así que realmente lo que queremos es solo definir la función del botón.De forma que se use de la siguiente manera: 
- 
-<sxh html;title:app.html> 
-<boton [funcion]="'peligrosa'">Hola mundo</boton> 
-</sxh> 
- 
- 
-  * Por lo tanto el atributo del botón va a ser ''funcion'' con los posibles valores de '''normal' | 'alternativa' | 'peligrosa''' . 
- 
-<sxh typescript;highlight: [11];  title: boton.html> 
-import {Component, Input} from '@angular/core'; 
-import {CommonModule} from '@angular/common'; 
- 
-@Component({ 
-  selector: 'boton', 
-  imports: [CommonModule], 
-  templateUrl: './boton.html', 
-  styleUrl: './boton.scss' 
-}) 
-export class Boton  { 
-  @Input() funcion:'normal' | 'alternativa' | 'peligrosa'='normal'; 
- 
-} 
-</sxh> 
- 
- 
-  * Ahora hay que definir las clases CSS en el archivo ''boton.scss'' 
- 
-<sxh css;highlight: [20-24,26-30,32-36];  title: boton.scss> 
-.boton { 
-  font-family: sans-serif; 
-  font-size: 16px; 
-  padding: 6px; 
- 
-  border-radius: 6px; 
-  border-width: 1px; 
-  border-style: solid; 
- 
-  display: inline-block; 
-  cursor: pointer; 
-  text-decoration: none; 
- 
- 
-  border-color: #0056b8; 
-  background-color: #0056b8; 
-  color: #ffffff; 
-} 
- 
-.funcion--normal { 
-  border-color: #0056b8; 
-  background-color: #0056b8; 
-  color: #ffffff; 
-} 
- 
-.funcion--alternativa { 
-  border-color: #ed8936; 
-  background-color: #ed8936; 
-  color: #ffffff; 
-} 
- 
-.funcion--peligrosa { 
-  border-color: #c53030; 
-  background-color: #c53030; 
-  color: #ffffff; 
-} 
- 
- 
-</sxh> 
- 
- 
-  * Y por último relacionamos la propiedad TypScript ''funcion'' con las clases CSS en el HTML de la siguiente forma: 
- 
-<sxh html;highlight: [1];title:boton.html> 
-<button class="boton funcion--{{funcion}}"> 
-  <ng-content></ng-content> 
-</button> 
-</sxh> 
- 
-<note tip> 
-Notar el truco de ''class="funcion--<nowiki>{{funcion}}</nowiki>"'' 
-</note> 
- 
-  * Otra forma alternativa sería: 
- 
-<sxh html;highlight: [1];title:boton.html> 
-<button class="boton" [ngClass]="['funcion--'+funcion]"> 
-  <ng-content></ng-content> 
-</button> 
-</sxh> 
- 
-===== Acción de href ===== 
-Por último vamos a añadir acciones al botón, como el ''onClick'' y el ''href'' 
- 
- 
-Para crear el atributo ''href'' hay que hacer 3 cambios: 
-  * Añadir la propiedad ''href'' a la clase ''Boton'' 
-  * Usar la propiedad en el HTML 
-  * Cambiar de tipo ''<button>'' a ''<a>'' 
- 
- 
-<sxh TypeScript;highlight: [12]; title:boton.ts> 
-import {Component, Input} from '@angular/core'; 
-import {CommonModule} from '@angular/common'; 
- 
-@Component({ 
-  selector: 'boton', 
-  imports: [CommonModule], 
-  templateUrl: './boton.html', 
-  styleUrl: './boton.scss' 
-}) 
-export class Boton  { 
-  @Input() funcion:'normal' | 'alternativa' | 'peligrosa'='normal'; 
-  @Input() href:string=""; 
- 
-} 
- 
-</sxh> 
- 
-<sxh html;highlight: [1,3]; title:boton.html> 
-  <a class="boton funcion--{{funcion}}" [attr.href]="href || null"> 
-    <ng-content></ng-content> 
-  </a> 
-</sxh> 
- 
-Hay que destacar que además de usar ahora ''href'' también hemos cambiado la etiqueta a ''<a>''. 
- 
-Hemos puesto  
-  [attr.href]="href || null" 
-en vez de simplemente  
-  href={{ href }} 
-porque si no hay nada en href, no se añadirá el atributo 
- 
-===== Acción onClick ===== 
-Queremos que se ejecute la función ''alerta()'' de nuestra aplicación al pulsar en el botón. 
- 
- 
-<sxh typescript;highlight: [14-16]; title:app.ts> 
-import { Component, signal } from '@angular/core'; 
-import { RouterOutlet } from '@angular/router'; 
-  
-  
-@Component({ 
-  selector: 'app-root', 
-  imports: [RouterOutlet], 
-  templateUrl: './app.html', 
-  styleUrl: './app.scss' 
-}) 
-export class App { 
-  protected readonly title = signal('prueba'); 
-  
-  alerta() : void { 
-    alert('Hola mundo'); 
-  } 
- 
-} 
-</sxh> 
- 
-En el HTML lo indicaremos así 
- 
-<sxh html;highlight: [13]; title:app.html> 
-<style> 
-</style> 
-    
-<h1 >Hola mundo</h1> 
-    
-<button matButton="filled"> 
-  Aceptar 
-</button> 
-  
-<br> 
-<br> 
-  
-<boton [funcion]="'peligrosa'" (onClick)="alerta()"  >Hola mundo</boton> 
-    
-<router-outlet /> 
-</sxh> 
- 
- 
-Para ello tenemos que hacer 3 cosas en el botón: 
-  * Decir que vamos a emitir un evento 
-  * Emitir el evento desde TypeScript  
-  * Enlazar el click de ''<a>'' con el TS 
- 
- 
- 
-<sxh typescript;highlight: [1,13,15-17]; title:boton.ts> 
-import {Component, EventEmitter, Input, Output} from '@angular/core'; 
-import {CommonModule} from '@angular/common'; 
- 
-@Component({ 
-  selector: 'boton', 
-  imports: [CommonModule], 
-  templateUrl: './boton.html', 
-  styleUrl: './boton.scss' 
-}) 
-export class Boton  { 
-  @Input() funcion:'normal' | 'alternativa' | 'peligrosa'='normal'; 
-  @Input() href:string=""; 
-  @Output() onClick = new EventEmitter<void>(); 
- 
-  handleOnClick(): void { 
-    this.onClick.emit(); 
-  } 
- 
-} 
- 
- 
-</sxh> 
- 
- 
- 
-<sxh html;highlight: [1]; title:boton.html> 
-  <a class="boton funcion--{{funcion}}" [attr.href]="href || null" (click)="handleOnClick()"> 
-    <ng-content></ng-content> 
-  </a> 
-</sxh> 
- 
- 
- 
-===== Filtros ===== 
-Angular permite modificar los datos cuando se interpolan en el html. 
- 
- 
-  * [[https://angular.dev/api/common/CurrencyPipe|''currency'']] : Permite mostrar un número como una moneda 
- 
-<sxh html> 
-<p>{{precio | currency}}</p> 
-</sxh> 
- 
-  * [[https://angular.dev/api/common/DatePipe|''date'']] : Permite formatear una fecha 
- 
-<sxh html> 
-<p>{{fechaCompra | date:'shortDate'}}</p> 
-</sxh> 
- 
- 
-Mas  
- 
-===== Ejercicios ===== 
- 
-==== Ejercicio 1 ==== 
- 
-Usando el elemento HTML de [[https://developer.mozilla.org/es/docs/Web/HTML/Reference/Elements/progress|<progress>]]. 
- 
-<sxh html> 
-<label for="file">File progress:</label> 
- 
-<progress id="file" max="100" value="70">70%</progress> 
-</sxh> 
- 
-Crea el componente ''<progreso>'' 
-<sxh html> 
-<progreso  [title]="'File progress:'" [porcentajeRealizado]="70" /> 
- 
-<boton (onClick)="incrementar()">Incrementar 10</boton> 
- 
-</sxh> 
- 
-y que muestre: 
- 
-{{:clase:daw:diw:1eval:file_progress.png?400|}} 
- 
-Añade en la página un botón de forma que al pulsarlo se incremente en 10 el valor. 
- 
-<note tip> 
-Para generar los ''id'' se usa la librería uuid 
- 
-<sxh bash> 
-npm install uuid 
-npm install --save-dev @types/uuid 
-</sxh> 
- 
- 
-<sxh typescript> 
-import { v4 as uuidv4 } from 'uuid'; 
- 
-class MiClase{ 
-  uniqueId: string; 
- 
-  constructor() { 
-    this.uniqueId =uuidv4(); 
-  } 
-} 
-</sxh> 
- 
-</note> 
- 
-==== Ejercicio 2 ==== 
-Crea un componente llamado panel que permita hacer los siguientes paneles 
- 
-{{:clase:daw:diw:1eval:ejercicio_paneles.png?400|}} 
- 
- 
-Y crea una página HTML donde se vean los paneles. 
- 
- 
-==== Ejercicio 3 ==== 
- 
-Crea ahora un componente para crear los siguientes botones: 
- 
-^   ^  Importancia  ^^^ 
-^  Función  |  Primaria  |  Secundaria  |  Terciaria  | 
-|  Normal  |  {{:clase:daw:diw:1eval:primary.png|}}  |  {{:clase:daw:diw:1eval:secondary.png|}}  |  {{:clase:daw:diw:1eval:tertiary.png|}}  | 
-|  Alternativa  |  {{:clase:daw:diw:1eval:alt-primary.png|}}  |  {{:clase:daw:diw:1eval:alt-secondary.png|}}  |  {{:clase:daw:diw:1eval:alt-tertiary.png|}}  | 
-|  Peligrosa  |  {{:clase:daw:diw:1eval:rojo-primary.png|}}  |  {{:clase:daw:diw:1eval:rojo-secondary.png|}}  |  {{:clase:daw:diw:1eval:rojo-tertiary.png|}}  | 
  
clase/daw/diw/1eval/tema03.1762357560.txt.gz · Última modificación: por Lorenzo