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
- Parent to Child Communication: Passing data from a parent component to a child component.
- Child to Parent Communication: Sending data from a child component to a parent component.
- Sibling Communication: Sharing data between sibling components.
- 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:
- 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; }
- 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 theChildComponent
allows thechildMessage
property to receive data from the parent component. - The parent component binds its
parentMessage
property to thechildMessage
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:
- 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!'); } }
- 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 theChildComponent
creates anEventEmitter
instance. - The
sendMessage
method emits a message using theEventEmitter
. - The parent component listens to the
messageEvent
using event binding(messageEvent)="receiveMessage($event)"
. - The
receiveMessage
method in the parent component updates themessage
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:
- 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); } }
- 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!'); } }
- 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 RxJSSubject
to facilitate communication. Sibling1Component
sends a message by callingchangeMessage
on theMessageService
.Sibling2Component
subscribes tocurrentMessage
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 andEventEmitter
. - 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.
Angular Course
Module 1: Introduction to Angular
- What is Angular?
- Setting Up the Development Environment
- Angular Architecture
- First Angular Application
Module 2: Angular Components
- Understanding Components
- Creating Components
- Component Templates
- Component Styles
- Component Interaction
Module 3: Data Binding and Directives
- Interpolation and Property Binding
- Event Binding
- Two-Way Data Binding
- Built-in Directives
- Custom Directives
Module 4: Services and Dependency Injection
Module 5: Routing and Navigation
Module 6: Forms in Angular
Module 7: HTTP Client and Observables
- Introduction to HTTP Client
- Making HTTP Requests
- Handling HTTP Responses
- Using Observables
- Error Handling
Module 8: State Management
- Introduction to State Management
- Using Services for State Management
- NgRx Store
- NgRx Effects
- NgRx Entity
Module 9: Testing in Angular
Module 10: Advanced Angular Concepts
- Angular Universal
- Performance Optimization
- Internationalization (i18n)
- Custom Pipes
- Angular Animations