In Angular, components are the building blocks of the application. Often, these components need to communicate with each other to share data and functionality. This communication is known as component interaction. In this section, we will explore various ways to achieve component interaction in Angular.

Key Concepts

  1. Parent to Child Communication: Passing data from a parent component to a child component.
  2. Child to Parent Communication: Sending data from a child component to a parent component.
  3. Sibling Communication: Sharing data between sibling components.
  4. Service-Based Communication: Using services to facilitate communication between components.

Parent to Child Communication

Using Input Decorator

The @Input decorator allows a parent component to bind to a property of a child component.

Example:

  1. Child Component (child.component.ts):
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `<p>{{ childMessage }}</p>`
})
export class ChildComponent {
  @Input() childMessage: string;
}
  1. Parent Component (parent.component.ts):
import { Component } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: `<app-child [childMessage]="parentMessage"></app-child>`
})
export class ParentComponent {
  parentMessage = 'Hello from Parent!';
}

Explanation:

  • The @Input decorator in the ChildComponent allows the childMessage property to receive data from the parent component.
  • The parent component binds its parentMessage property to the childMessage property of the child component using property binding [childMessage]="parentMessage".

Child to Parent Communication

Using Output Decorator and EventEmitter

The @Output decorator and EventEmitter allow a child component to emit events that a parent component can listen to.

Example:

  1. Child Component (child.component.ts):
import { Component, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `<button (click)="sendMessage()">Send Message</button>`
})
export class ChildComponent {
  @Output() messageEvent = new EventEmitter<string>();

  sendMessage() {
    this.messageEvent.emit('Hello from Child!');
  }
}
  1. Parent Component (parent.component.ts):
import { Component } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: `
    <app-child (messageEvent)="receiveMessage($event)"></app-child>
    <p>{{ message }}</p>
  `
})
export class ParentComponent {
  message: string;

  receiveMessage($event: string) {
    this.message = $event;
  }
}

Explanation:

  • The @Output decorator in the ChildComponent creates an EventEmitter instance.
  • The sendMessage method emits a message using the EventEmitter.
  • The parent component listens to the messageEvent using event binding (messageEvent)="receiveMessage($event)".
  • The receiveMessage method in the parent component updates the message property with the received event data.

Sibling Communication

Using a Shared Service

Sibling components can communicate through a shared service that acts as a mediator.

Example:

  1. Message Service (message.service.ts):
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class MessageService {
  private messageSource = new Subject<string>();
  currentMessage = this.messageSource.asObservable();

  changeMessage(message: string) {
    this.messageSource.next(message);
  }
}
  1. Sibling Component 1 (sibling1.component.ts):
import { Component } from '@angular/core';
import { MessageService } from './message.service';

@Component({
  selector: 'app-sibling1',
  template: `<button (click)="sendMessage()">Send Message</button>`
})
export class Sibling1Component {
  constructor(private messageService: MessageService) {}

  sendMessage() {
    this.messageService.changeMessage('Hello from Sibling 1!');
  }
}
  1. Sibling Component 2 (sibling2.component.ts):
import { Component, OnInit } from '@angular/core';
import { MessageService } from './message.service';

@Component({
  selector: 'app-sibling2',
  template: `<p>{{ message }}</p>`
})
export class Sibling2Component implements OnInit {
  message: string;

  constructor(private messageService: MessageService) {}

  ngOnInit() {
    this.messageService.currentMessage.subscribe(message => this.message = message);
  }
}

Explanation:

  • The MessageService uses an RxJS Subject to facilitate communication.
  • Sibling1Component sends a message by calling changeMessage on the MessageService.
  • Sibling2Component subscribes to currentMessage to receive updates.

Summary

In this section, we explored various methods for component interaction in Angular:

  • Parent to Child Communication using the @Input decorator.
  • Child to Parent Communication using the @Output decorator and EventEmitter.
  • Sibling Communication using a shared service.

Understanding these methods is crucial for building complex, interactive Angular applications. In the next module, we will delve into data binding and directives, which are essential for dynamic and responsive user interfaces.

© Copyright 2024. All rights reserved