La interacción entre componentes es un aspecto fundamental en Angular, ya que permite que los componentes se comuniquen entre sí para compartir datos y comportamientos. En esta sección, aprenderemos diferentes métodos para lograr esta comunicación.
Métodos de Interacción entre Componentes
- Input y Output Properties
- ViewChild y ContentChild
- Servicios para Comunicación entre Componentes
- Input y Output Properties
Input Properties
Las propiedades de entrada (@Input
) permiten que un componente padre pase datos a un componente hijo.
Ejemplo:
// hijo.component.ts import { Component, Input } from '@angular/core'; @Component({ selector: 'app-hijo', template: `<p>{{ mensaje }}</p>` }) export class HijoComponent { @Input() mensaje: string; }
Output Properties
Las propiedades de salida (@Output
) permiten que un componente hijo envíe datos a un componente padre mediante eventos.
Ejemplo:
// hijo.component.ts import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-hijo', template: `<button (click)="enviarMensaje()">Enviar Mensaje</button>` }) export class HijoComponent { @Output() mensajeEnviado = new EventEmitter<string>(); enviarMensaje() { this.mensajeEnviado.emit('Mensaje desde el componente hijo'); } }
// padre.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-padre', template: `<app-hijo (mensajeEnviado)="recibirMensaje($event)"></app-hijo>` }) export class PadreComponent { recibirMensaje(mensaje: string) { console.log(mensaje); } }
- ViewChild y ContentChild
ViewChild
@ViewChild
se utiliza para acceder a un componente hijo desde el componente padre.
Ejemplo:
// hijo.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-hijo', template: `<p>Componente Hijo</p>` }) export class HijoComponent { saludar() { console.log('Hola desde el componente hijo'); } }
// padre.component.ts import { Component, ViewChild, AfterViewInit } from '@angular/core'; import { HijoComponent } from './hijo.component'; @Component({ selector: 'app-padre', template: `<app-hijo></app-hijo>` }) export class PadreComponent implements AfterViewInit { @ViewChild(HijoComponent) hijo: HijoComponent; ngAfterViewInit() { this.hijo.saludar(); } }
ContentChild
@ContentChild
se utiliza para acceder a un componente hijo proyectado en una plantilla.
Ejemplo:
// hijo.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-hijo', template: `<p>Componente Hijo</p>` }) export class HijoComponent {}
// padre.component.ts import { Component, ContentChild, AfterContentInit } from '@angular/core'; import { HijoComponent } from './hijo.component'; @Component({ selector: 'app-padre', template: `<ng-content></ng-content>` }) export class PadreComponent implements AfterContentInit { @ContentChild(HijoComponent) hijo: HijoComponent; ngAfterContentInit() { console.log(this.hijo); } }
- Servicios para Comunicación entre Componentes
Los servicios pueden ser utilizados para compartir datos y comportamientos entre componentes que no tienen una relación directa de padre-hijo.
Ejemplo:
// mensaje.service.ts import { Injectable } from '@angular/core'; import { Subject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class MensajeService { private mensajeSource = new Subject<string>(); mensaje$ = this.mensajeSource.asObservable(); enviarMensaje(mensaje: string) { this.mensajeSource.next(mensaje); } }
// componente1.component.ts import { Component } from '@angular/core'; import { MensajeService } from './mensaje.service'; @Component({ selector: 'app-componente1', template: `<button (click)="enviarMensaje()">Enviar Mensaje</button>` }) export class Componente1Component { constructor(private mensajeService: MensajeService) {} enviarMensaje() { this.mensajeService.enviarMensaje('Mensaje desde Componente 1'); } }
// componente2.component.ts import { Component, OnInit } from '@angular/core'; import { MensajeService } from './mensaje.service'; @Component({ selector: 'app-componente2', template: `<p>{{ mensaje }}</p>` }) export class Componente2Component implements OnInit { mensaje: string; constructor(private mensajeService: MensajeService) {} ngOnInit() { this.mensajeService.mensaje$.subscribe(mensaje => this.mensaje = mensaje); } }
Ejercicio Práctico
Ejercicio
- Crea un componente padre y un componente hijo.
- Utiliza
@Input
para pasar un mensaje del componente padre al componente hijo. - Utiliza
@Output
para enviar un evento desde el componente hijo al componente padre. - Utiliza
@ViewChild
para acceder a un método del componente hijo desde el componente padre.
Solución
Paso 1: Crear los componentes
Paso 2: Utilizar @Input
// hijo.component.ts import { Component, Input } from '@angular/core'; @Component({ selector: 'app-hijo', template: `<p>{{ mensaje }}</p>` }) export class HijoComponent { @Input() mensaje: string; }
Paso 3: Utilizar @Output
// hijo.component.ts import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-hijo', template: `<button (click)="enviarMensaje()">Enviar Mensaje</button>` }) export class HijoComponent { @Output() mensajeEnviado = new EventEmitter<string>(); enviarMensaje() { this.mensajeEnviado.emit('Mensaje desde el componente hijo'); } }
// padre.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-padre', template: `<app-hijo (mensajeEnviado)="recibirMensaje($event)"></app-hijo>` }) export class PadreComponent { recibirMensaje(mensaje: string) { console.log(mensaje); } }
Paso 4: Utilizar @ViewChild
// hijo.component.ts import { Component } from '@angular/core'; @Component({ selector: 'app-hijo', template: `<p>Componente Hijo</p>` }) export class HijoComponent { saludar() { console.log('Hola desde el componente hijo'); } }
// padre.component.ts import { Component, ViewChild, AfterViewInit } from '@angular/core'; import { HijoComponent } from './hijo.component'; @Component({ selector: 'app-padre', template: `<app-hijo></app-hijo>` }) export class PadreComponent implements AfterViewInit { @ViewChild(HijoComponent) hijo: HijoComponent; ngAfterViewInit() { this.hijo.saludar(); } }
Conclusión
En esta sección, hemos aprendido diferentes métodos para la interacción entre componentes en Angular, incluyendo @Input
, @Output
, @ViewChild
, @ContentChild
y el uso de servicios. Estos métodos son esenciales para construir aplicaciones Angular robustas y bien estructuradas. En el próximo módulo, exploraremos las directivas y pipes, que nos permitirán manipular el DOM y transformar datos de manera eficiente.
Curso de Angular 2+
Módulo 1: Introducción a Angular
- ¿Qué es Angular?
- Configuración del Entorno de Desarrollo
- Tu Primera Aplicación Angular
- Arquitectura de Angular
Módulo 2: Conceptos Básicos de TypeScript
- Introducción a TypeScript
- Variables y Tipos de Datos en TypeScript
- Funciones y Funciones Flecha
- Clases e Interfaces
Módulo 3: Componentes y Plantillas
- Creación de Componentes
- Plantillas de Componentes
- Estilos de Componentes
- Interacción entre Componentes
Módulo 4: Directivas y Pipes
Módulo 5: Servicios e Inyección de Dependencias
- Introducción a los Servicios
- Creación y Uso de Servicios
- Inyección de Dependencias
- Inyectores Jerárquicos
Módulo 6: Enrutamiento y Navegación
Módulo 7: Formularios en Angular
- Formularios Basados en Plantillas
- Formularios Reactivos
- Validación de Formularios
- Formularios Dinámicos
Módulo 8: Cliente HTTP y Observables
- Introducción al Cliente HTTP
- Realizando Solicitudes HTTP
- Manejo de Respuestas HTTP
- Uso de Observables
Módulo 9: Gestión de Estado
- Introducción a la Gestión de Estado
- Uso de Servicios para la Gestión de Estado
- NgRx Store
- NgRx Effects