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 
@Inputpara pasar un mensaje del componente padre al componente hijo. - Utiliza 
@Outputpara enviar un evento desde el componente hijo al componente padre. - Utiliza 
@ViewChildpara 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
 
