Angular: Comunicacion Entre Componentes

Comunicación entre componentes en Angular

La comunicación entre componentes en Angular es esencial para la creación de aplicaciones complejas y estructuradas. Permite a los componentes compartir datos y responder a eventos entre ellos. Esto se puede lograr de varias maneras:

  1. Input/Output Binding: Uso de decoradores @Input y @Output para pasar datos y emitir eventos entre componentes padre e hijo.
  2. Servicios: Uso de servicios para compartir datos y lógica entre componentes que no están directamente relacionados.
  3. Template Reference Variables: Uso de variables de referencia en plantillas para interactuar directamente con componentes hijo.
  4. ViewChild/ViewChildren: Uso de decoradores @ViewChild y @ViewChildren para acceder a instancias de componentes hijo desde el componente padre.

Componentes de Comunicación Entre Componentes en Angular v18

  1. @Input: Decorador que permite que un componente reciba datos de un componente padre.
  2. @Output: Decorador que permite que un componente emita eventos hacia un componente padre.
  3. EventEmitter: Clase utilizada junto con @Output para emitir eventos.
  4. Servicios: Clases inyectables que pueden ser compartidas entre componentes para mantener y gestionar estados o lógica de negocio.
  5. Template Reference Variables: Variables definidas en la plantilla para referenciar componentes o elementos DOM.
  6. @ViewChild: Decorador que permite acceder a un solo elemento hijo en el DOM.
  7. @ViewChildren: Decorador que permite acceder a múltiples elementos hijos en el DOM.

Videotutorial: 

  1. Curso Angular 2023 #6 Comunicacion Entre Componentes En Angular: https://youtu.be/m5vQDATqqiY?list=PLxjAmQnB-4D-zYOs2sT68_6btSZ1Vuzj4
  2. Filtro dinámico - Comunicación entre componentes I:  https://youtu.be/r_6eqIOGpDM?list=PLysCxvRbcLqA3BnWfkzH7lVeIMn5uNx8c 
  3. Filtro dinámico - Comunicación entre componentes II: https://youtu.be/hKrSgro318I?list=PLysCxvRbcLqA3BnWfkzH7lVeIMn5uNx8c
  4.  Filtro dinámico - Comunicación entre componentes III: https://youtu.be/_VWefW3ZT8Q
  5. .. 

 

@Input:

  • Se usa para recibir datos de un componente padre.
import { Component, Input } from '@angular/core';

@Component({
  selector: 'child-component',
  template: `

{{ data }}

` }) export class ChildComponent { @Input() data: string; }

 

@Output:

  • Se usa para emitir eventos a un componente padre.
import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'child-component',
  template: `<button (click)="sendData()">Send Data</button>`
})
export class ChildComponent {
  @Output() dataEmitter = new EventEmitter<string>();

  sendData() {
    this.dataEmitter.emit('Hello from Child');
  }
}
</string>

 

EventEmitter

EventEmitter: Clase utilizada para emitir eventos personalizados. Se usa junto con @Output.

import { EventEmitter } from '@angular/core';
this.dataEmitter = new EventEmitter<string>();

 

Servicios

Servicios: Clases que contienen lógica y datos compartidos entre componentes.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private data: string;

  setData(data: string) {
    this.data = data;
  }

  getData(): string {
    return this.data;
  }
}

 

Servicios

Servicios: Clases que contienen lógica y datos compartidos entre componentes.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private data: string;

  setData(data: string) {
    this.data = data;
  }

  getData(): string {
    return this.data;
  }
}

 

Template Reference Variables

Template Reference Variables: Se usan en las plantillas para referenciar elementos DOM o componentes.

<child-component #child></child-component>
<button (click)="child.sendData()">Trigger Child Method</button>

 

@ViewChild:

  • Se usa para acceder a un componente hijo desde el componente padre.
import { Component, ViewChild } from '@angular/core';
import { ChildComponent } from './child.component';

@Component({
  selector: 'parent-component',
  template: `
    
  `
})
export class ParentComponent {
  @ViewChild(ChildComponent) childComponent: ChildComponent;

  ngAfterViewInit() {
    this.childComponent.sendData();
  }
}

mm

import { Component, ViewChildren, QueryList } from '@angular/core';
import { ChildComponent } from './child.component';

@Component({
  selector: 'parent-component',
  template: `
    <child-component></child-component>
<child-component></child-component> ` }) export class ParentComponent { @ViewChildren(ChildComponent) children: QueryList<ChildComponent>; ngAfterViewInit() { this.children.forEach(child => child.sendData()); } }

 

Ejemplo de Comunicación Entre Componentes

Este ejemplo muestra cómo los componentes pueden comunicarse entre sí usando @Input, @Output, EventEmitter, y un servicio compartido. Los datos pueden fluir del componente padre al componente hijo a través de @Input y en la dirección opuesta a través de @Output y EventEmitter. Además, un servicio puede mantener y proporcionar datos compartidos a través de múltiples componentes.

 Configuración del módulo:

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ParentComponent } from './parent.component';
import { ChildComponent } from './child.component';

@NgModule({
  declarations: [AppComponent, ParentComponent, ChildComponent],
  imports: [BrowserModule],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

 

Servicio de datos compartidos:

// data.service.ts
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private data: string;

  setData(data: string) {
    this.data = data;
  }

  getData(): string {
    return this.data;
  }
}

 

Componente Hijo:

// child.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'child-component',
  template: `
    <div>
<p>Data from parent: {{ data }}</p>
<button (click)="sendData()">Send Data to Parent</button>
</div> ` }) export class ChildComponent { @Input() data: string; @Output() dataEmitter = new EventEmitter<string>(); sendData() { this.dataEmitter.emit('Data from Child'); } } </string>

 

Componente Padre:

// parent.component.ts
import { Component, ViewChild } from '@angular/core';
import { ChildComponent } from './child.component';
import { DataService } from './data.service';

@Component({
  selector: 'parent-component',
  template: `
    <div>
<h2>Parent Component</h2>
<button (click)="sendDataToChild()">Send Data to Child</button>
<child-component [data]="parentData" (dataEmitter)="receiveData($event)"></child-component>
</div> ` }) export class ParentComponent { parentData: string = 'Data from Parent'; @ViewChild(ChildComponent) childComponent: ChildComponent; constructor(private dataService: DataService) {} sendDataToChild() { this.dataService.setData('Updated Data from Parent'); this.childComponent.data = this.dataService.getData(); } receiveData(data: string) { console.log('Received data from child:', data); } }

 

Componente Principal:

// app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <div>
<h1>Angular Communication Example</h1>
<parent-component></parent-component>
</div> ` }) export class AppComponent {}

mm