Introducción: Los componentes son fundamentales en Angular. En este capítulo, exploraremos en detalle cómo trabajar con componentes en Angular, incluyendo su creación, la comunicación entre componentes, el uso de directivas estructurales y el ciclo de vida de un componente.
2.1. Creación de componentes
- ¿Qué son los componentes en Angular? En Angular, los componentes son la unidad básica de la interfaz de usuario. Cada componente consiste en una vista (plantilla HTML), la lógica que controla esa vista (archivo TypeScript) y, opcionalmente, estilos (hojas de estilo CSS o SCSS). Los componentes se utilizan para dividir la interfaz de usuario en partes más pequeñas y reutilizables.
- Creación de componentes personalizados Puedes crear componentes personalizados en Angular utilizando Angular CLI o manualmente. La creación manual implica definir un archivo TypeScript, una plantilla HTML y, opcionalmente, un archivo de estilo.
- Estructura de un componente Un componente en Angular consta de tres partes principales: el archivo TypeScript que define la lógica, la plantilla HTML que define la vista y, opcionalmente, un archivo de estilo que define la apariencia. En el archivo TypeScript, se definen las propiedades y métodos del componente.
Aquí tienes un ejemplo de la estructura básica de un componente en Angular, que incluye el archivo TypeScript, la plantilla HTML y la hoja de estilo CSS:
Estructura de un componente en Angular:
Archivo TypeScript (product.component.ts):
import { Component } from '@angular/core';
@Component({
selector: 'app-product', // Selector del componente
templateUrl: './product.component.html', // Ruta a la plantilla HTML
styleUrls: ['./product.component.css'] // Ruta a la hoja de estilo CSS
})
export class ProductComponent {
// Propiedades y lógica del componente
productName: string = 'Producto de ejemplo';
}
Plantilla HTML (product.component.html):
<!-- Plantilla HTML del componente -->
<div>
<h2>Detalles del Producto</h2>
<p>Nombre del Producto: {{ productName }}</p>
</div>
Hoja de estilo CSS (product.component.css):
/* Hoja de estilo CSS del componente */
h2 {
color: #333;
}
p {
font-size: 18px;
color: #666;
}
En este ejemplo:
- El archivo TypeScript (
product.component.ts
) contiene la definición del componente, incluyendo su selector, la ruta a la plantilla HTML y la ruta a la hoja de estilo CSS. También define la clase del componente, donde puedes agregar propiedades y lógica específica del componente. - La plantilla HTML (
product.component.html
) define la estructura visual del componente. Utiliza interpolación{{}}
para mostrar el valor de la propiedadproductName
. - La hoja de estilo CSS (
product.component.css
) contiene reglas de estilo para personalizar la apariencia del componente. En este caso, se establecen estilos para los elementosh2
yp
.
Esta es la estructura básica de un componente en Angular. El archivo TypeScript define la lógica y las propiedades, la plantilla HTML define la estructura visual y la hoja de estilo CSS define los estilos para el componente. Cuando este componente se utiliza en una aplicación Angular, se renderizará en la vista según la plantilla HTML y se aplicarán los estilos definidos en la hoja de estilo CSS.
- Enlace de datos en componentes Angular admite el enlace de datos bidireccional, lo que significa que los datos pueden fluir tanto desde el componente a la vista como desde la vista al componente. Esto permite una actualización automática de la vista cuando los datos cambian en el componente.
Aquí tienes un ejemplo de enlace de datos en componentes de Angular. Supongamos que tenemos un componente llamado ProductComponent
que muestra información de un producto y permite a los usuarios cambiar el nombre del producto mediante un formulario de entrada.
product.component.ts (archivo TypeScript):
import { Component } from '@angular/core';
@Component({
selector: 'app-product',
templateUrl: './product.component.html',
})
export class ProductComponent {
productName: string = 'Producto inicial'; // Propiedad del componente
// Método para cambiar el nombre del producto
changeProductName(newName: string) {
this.productName = newName;
}
}
product.component.html (plantilla HTML):
<div>
<h2>Detalles del Producto</h2>
<p>Nombre del Producto: {{ productName }}</p>
<label for="newName">Nuevo Nombre del Producto:</label>
<input type="text" id="newName" [(ngModel)]="productName">
<button (click)="changeProductName('Producto Modificado')">Cambiar Nombre</button>
</div>
En este ejemplo:
- El componente
ProductComponent
tiene una propiedad llamadaproductName
que representa el nombre del producto. Este nombre se muestra en la plantilla. - En la plantilla HTML, utilizamos el enlace de datos para mostrar el valor de
productName
en la etiqueta<p>
. Cualquier cambio enproductName
se reflejará automáticamente en la vista. - También tenemos un formulario de entrada con
[(ngModel)]="productName"
, que permite a los usuarios cambiar el nombre del producto. El enlace bidireccional(ngModel)
asegura que cualquier cambio en el formulario actualice la propiedadproductName
en el componente y, a su vez, actualice la vista. - Finalmente, tenemos un botón que llama al método
changeProductName
cuando se hace clic. Este método cambia el nombre del producto en el componente, lo que también se reflejará en la vista debido al enlace de datos.
El enlace de datos en Angular permite una comunicación fluida entre los componentes y la vista, lo que facilita la actualización de la interfaz de usuario en función de los cambios en los datos del componente.
2.2. Comunicación entre componentes
- Comunicación entre componentes en Angular En una aplicación Angular, es común que los componentes necesiten comunicarse entre sí. Esto se puede lograr de diversas maneras:
- Comunicación entre componentes padres e hijos: Los componentes pueden pasar datos desde componentes padres a componentes hijos utilizando propiedades de entrada (Input).
- Comunicación entre componentes hijos y padres: Los componentes hijos pueden comunicarse con sus componentes padres utilizando eventos personalizados.
- Servicios compartidos: Los servicios pueden utilizarse como intermediarios para la comunicación entre componentes que no están directamente relacionados en la jerarquía de componentes.
La comunicación entre componentes en Angular se puede lograr de varias formas, y una de las formas más comunes es a través de la interacción entre componentes padres e hijos. Aquí tienes una tabla que muestra cómo se puede lograr la comunicación entre componentes en Angular:
Tipo de Comunicación | Descripción |
Propiedades de Entrada (Input) | Un componente padre puede pasar datos a un componente hijo utilizando propiedades de entrada (Input). En el componente hijo, estas propiedades se decoran con @Input() , lo que permite que el padre proporcione datos al componente hijo. |
Eventos Personalizados | Un componente hijo puede emitir eventos personalizados que son capturados por un componente padre. Los eventos personalizados se definen en el componente hijo y se capturan en el componente padre utilizando el enlace (event) en la plantilla. |
Servicios Compartidos | Los servicios son instancias compartidas que pueden ser inyectadas en múltiples componentes. Los componentes pueden utilizar un servicio compartido para intercambiar datos y comunicarse. |
ViewChild y ViewChildren | ViewChild y ViewChildren son decoradores que permiten a un componente padre acceder a instancias de componentes hijos directos o elementos del DOM dentro de la vista. Esto se utiliza para interactuar con componentes hijos directamente. |
Output Decorator | El decorador @Output se utiliza para emitir eventos personalizados desde un componente hijo. Los eventos emitidos pueden ser capturados por un componente padre y utilizados para comunicarse con el componente hijo. |
Estas son algunas de las formas más comunes de lograr la comunicación entre componentes en Angular. La elección de la técnica depende de la relación entre los componentes y de la dirección de la comunicación (de padre a hijo o de hijo a padre). Puedes utilizar una o varias de estas técnicas en función de los requisitos de tu aplicación.
2.3. Directivas estructurales
- ¿Qué son las directivas estructurales en Angular? En Angular, las directivas estructurales son instrucciones en la plantilla HTML que te permiten modificar la estructura del DOM (Document Object Model) de tu aplicación en función de condiciones específicas. Las directivas estructurales se utilizan comúnmente para controlar la visibilidad, repetir elementos y alterar la estructura de la página. A continuación, se mencionan todas las directivas estructurales en Angular:
- NgIf: Permite agregar o eliminar elementos del DOM en función de una expresión condicional. Por ejemplo, puedes mostrar u ocultar un elemento según una condición.
- NgFor: Se utiliza para iterar sobre una colección (como un arreglo) y crear elementos repetidos en el DOM. Puedes usarlo para mostrar una lista de elementos o repetir un contenido de acuerdo con una estructura de datos.
- NgSwitch: Permite realizar una selección entre varias opciones basadas en una expresión. Puedes usarlo para alternar entre diferentes bloques de contenido según el valor de una variable.
- NgSwitchCase: Se utiliza junto con
NgSwitch
para definir los casos específicos a considerar dentro de una estructura de conmutación (switch). - NgSwitchDefault: Define el caso predeterminado cuando ningún caso de
NgSwitchCase
coincide con la expresión deNgSwitch
. - NgTemplateOutlet: Permite insertar dinámicamente contenido en una plantilla usando un marcador de posición. Es útil para la generación dinámica de plantillas.
- NgForOf: Una variante optimizada de
NgFor
que se utiliza para iterar sobre iterables de Angular, comoNgForOf
yNgForTrackBy
.
Estas son las principales directivas estructurales en Angular que te permiten controlar la estructura del DOM en función de condiciones o iterar sobre datos. Puedes utilizar estas directivas para crear plantillas dinámicas y adaptar la visualización de tu aplicación web a diferentes situaciones.
- Uso de
*ngIf
y*ngFor
Aprenderás cómo utilizar las directivas estructurales*ngIf
y*ngFor
en ejemplos prácticos.*ngIf
se utiliza para mostrar o ocultar elementos según una condición, y*ngFor
se utiliza para repetir elementos basados en una lista de datos.
2.4. Ciclo de vida de un componente
- El ciclo de vida de un componente en Angular Los componentes en Angular pasan por una serie de fases o estados desde su creación hasta su destrucción. Comprender el ciclo de vida de un componente es esencial para realizar tareas como inicialización de datos, ejecución de código después de que la vista se ha renderizado y limpieza de recursos.
- Métodos del ciclo de vida del componente Aprenderás acerca de los métodos del ciclo de vida del componente, como
ngOnInit
,ngOnChanges
,ngAfterViewInit
,ngOnDestroy
y otros. Estos métodos te permiten realizar acciones específicas en diferentes momentos del ciclo de vida del componente.
Aquí tienes una tabla que representa el ciclo de vida de un componente en Angular y las fases clave del ciclo de vida del componente:
Fase del Ciclo de Vida | Descripción |
ngOnChanges | Se llama cuando los valores de las propiedades de entrada (@Input() ) del componente cambian. Permite detectar cambios en las entradas y realizar acciones en respuesta a estos cambios. |
ngOnInit | Se llama una vez que el componente ha sido inicializado. Es el lugar adecuado para realizar tareas de inicialización, como obtener datos iniciales o configurar sus propiedades. |
ngDoCheck | Se llama durante cada ciclo de detección de cambios en Angular. Permite realizar tareas de detección de cambios personalizadas y optimizaciones manuales. |
ngAfterContentInit | Se llama después de que el contenido proyectado (proyecciones de contenido) ha sido inicializado. Es útil cuando un componente contiene contenido proyectado (ng-content) y necesita interactuar con él. |
ngAfterContentChecked | Se llama después de cada ciclo de detección de cambios que verifica el contenido proyectado. Permite realizar acciones después de que se haya verificado el contenido proyectado. |
ngAfterViewInit | Se llama después de que la vista del componente y sus vistas secundarias (hijas) se hayan inicializado. Puede usarse para interactuar con el DOM después de que la vista esté lista. |
ngAfterViewChecked | Se llama después de cada ciclo de detección de cambios que verifica la vista y sus vistas secundarias. Permite realizar acciones después de que se haya verificado la vista. |
ngOnDestroy | Se llama justo antes de que se elimine un componente. Es el lugar adecuado para realizar la limpieza de recursos, como la eliminación de suscripciones a observables o la liberación de recursos. |
Estas son las principales fases del ciclo de vida de un componente en Angular. Cada fase se llama en un momento específico durante la vida útil del componente y permite realizar acciones y lógica personalizadas en respuesta a eventos específicos.
2.5. Ejemplos Prácticos:
- Creación de componentes personalizados en Angular Te guiaré a través del proceso de creación de componentes personalizados en Angular utilizando Angular CLI. También verás cómo definir propiedades de entrada (Input) en un componente.
- Comunicación entre componentes Verás ejemplos prácticos de comunicación entre componentes, incluyendo cómo pasar datos desde un componente padre a un componente hijo utilizando propiedades de entrada y cómo emitir eventos desde un componente hijo para comunicarse con un componente padre.
- Uso de directivas estructurales Aprenderás a utilizar directivas estructurales como
*ngIf
y*ngFor
en ejemplos prácticos. Verás cómo condicionar la visualización de elementos y cómo iterar sobre listas de datos en tus plantillas. - Gestión del ciclo de vida del componente Te mostraré cómo utilizar los métodos del ciclo de vida del componente en ejemplos prácticos. Aprenderás a realizar tareas de inicialización, limpieza de recursos y ejecución de código en momentos específicos del ciclo de vida del componente.
Aquí tienes un ejemplo de cómo crear componentes personalizados en Angular, establecer la comunicación entre componentes, utilizar directivas estructurales y gestionar el ciclo de vida del componente. En este ejemplo, construiremos una lista de tareas donde los componentes interactuarán entre sí.
- Creación de Componentes Personalizados:
Crearemos tres componentes: TaskListComponent
, AddTaskComponent
y TaskItemComponent
.
task-list.component.ts (TaskListComponent):
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-task-list',
templateUrl: './task-list.component.html',
})
export class TaskListComponent implements OnInit {
tasks: string[] = [];
ngOnInit() {
// Inicializamos la lista de tareas con algunas tareas de ejemplo
this.tasks = ['Tarea 1', 'Tarea 2', 'Tarea 3'];
}
addTask(newTask: string) {
this.tasks.push(newTask);
}
}
add-task.component.ts (AddTaskComponent):
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-add-task',
templateUrl: './add-task.component.html',
})
export class AddTaskComponent {
newTask: string = '';
@Output() taskAdded = new EventEmitter<string>();
addTask() {
this.taskAdded.emit(this.newTask);
this.newTask = '';
}
}
task-item.component.ts (TaskItemComponent):
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-task-item',
templateUrl: './task-item.component.html',
})
export class TaskItemComponent {
@Input() task: string = '';
}
Plantillas HTML:
task-list.component.html:
<h2>Lista de Tareas</h2>
<ul>
<li *ngFor="let task of tasks">
<app-task-item [task]="task"></app-task-item>
</li>
</ul>
<app-add-task (taskAdded)="addTask($event)"></app-add-task>
add-task.component.html:
<div>
<input type="text" [(ngModel)]="newTask" placeholder="Nueva Tarea">
<button (click)="addTask()">Agregar Tarea</button>
</div>
task-item.component.html:
{{ task }}
Comunicación entre Componentes:
TaskListComponent
muestra la lista de tareas y recibe nuevas tareas del componente AddTaskComponent
.
AddTaskComponent
emite un evento taskAdded
cuando se agrega una nueva tarea.
TaskItemComponent
muestra una tarea individual y recibe la tarea a mostrar desde TaskListComponent
.
Directivas Estructurales:
*ngFor
se utiliza en task-list.component.html
para repetir elementos y mostrar la lista de tareas.
*ngFor
se utiliza para iterar sobre las tareas y crear elementos <app-task-item>
para cada tarea.
Gestión del Ciclo de Vida:
ngOnInit
en TaskListComponent
se utiliza para inicializar la lista de tareas.
No es necesario gestionar explícitamente otras fases del ciclo de vida en este ejemplo, pero puedes implementarlas si es necesario.
Este ejemplo muestra la creación de componentes personalizados, la comunicación entre ellos, el uso de directivas estructurales (*ngFor
) y una parte de la gestión del ciclo de vida (ngOnInit
) en Angular. Puedes ampliar este ejemplo para incluir más funcionalidad y características según tus necesidades.
Este capítulo profundiza en la creación y gestión de componentes en Angular, así como en la comunicación entre ellos y el uso de directivas estructurales. Además, aprenderás cómo aprovechar el ciclo de vida del componente para realizar tareas específicas en momentos cruciales. Los ejemplos prácticos te ayudarán a aplicar estos conceptos en situaciones reales.