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

  1. Input y Output Properties
  2. ViewChild y ContentChild
  3. Servicios para Comunicación entre Componentes

  1. 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;
}
<!-- padre.component.html -->
<app-hijo [mensaje]="'Hola desde el componente padre'"></app-hijo>

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.html -->
<app-hijo (mensajeEnviado)="recibirMensaje($event)"></app-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);
  }
}

  1. 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);
  }
}
<!-- app.component.html -->
<app-padre>
  <app-hijo></app-hijo>
</app-padre>

  1. 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

  1. Crea un componente padre y un componente hijo.
  2. Utiliza @Input para pasar un mensaje del componente padre al componente hijo.
  3. Utiliza @Output para enviar un evento desde el componente hijo al componente padre.
  4. Utiliza @ViewChild para acceder a un método del componente hijo desde el componente padre.

Solución

Paso 1: Crear los componentes

ng generate component padre
ng generate component hijo

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;
}
<!-- padre.component.html -->
<app-hijo [mensaje]="'Hola desde el componente padre'"></app-hijo>

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.html -->
<app-hijo (mensajeEnviado)="recibirMensaje($event)"></app-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

Módulo 2: Conceptos Básicos de TypeScript

Módulo 3: Componentes y Plantillas

Módulo 4: Directivas y Pipes

Módulo 5: Servicios e Inyección de Dependencias

Módulo 6: Enrutamiento y Navegación

Módulo 7: Formularios en Angular

Módulo 8: Cliente HTTP y Observables

Módulo 9: Gestión de Estado

Módulo 10: Pruebas en Angular

Módulo 11: Temas Avanzados

Módulo 12: Despliegue y Mejores Prácticas

© Copyright 2024. Todos los derechos reservados