The code below demonstrates the communication between sibling components, parent and child components with the help of angular services.
app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { ParentComponent } from './app.parent.component'; import { ChildComponent } from './child.component'; @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ ParentComponent, ChildComponent ], bootstrap: [ ParentComponent ] }) export class AppModule {}
app.parent.component.ts
import { Component } from '@angular/core'; import { ParentChildService } from './parent-child.service'; @Component({ selector: 'parent-app', template: ` <div> <div> <h1>Hello from Parent</h1> </div> <div style="border: 1px dotted blue;"> <p> <b> Child message history </b> </p> <p *ngFor="let message of childMessages"> {{ message }} </p> </div> <child-app [id] = 1> </child-app> <child-app [id] = 2> </child-app> </div> `, providers: [ ParentChildService ] }) export class ParentComponent { childMessages: string[] = []; constructor(private parentChildService: ParentChildService) { parentChildService.attentionRequested$.subscribe((request) => { this.childMessages.push(this.parentChildService.requestedBy + ": " + request); }); } }
child.component.ts
import { Component, OnDestroy, Input } from '@angular/core'; import { ParentChildService } from './parent-child.service'; import { Subscription } from 'rxjs/Subscription'; @Component({ selector: 'child-app', template: ` <div> <div> <h2>Hello from {{ id }} child component</h2> <span> Message: </span> <input type="text" [(ngModel)]="message"> <button (click) = "requestAttention();"> Request </button> </div> <div style="border: 1px dotted green;"> <p> <b> Sibling message history </b> </p> <p *ngFor="let message of siblingMessages"> {{ message }} </p> </div> </div> ` }) export class ChildComponent implements OnDestroy { message: string; subscription: Subscription; siblingMessages: string[] = []; @Input() id: number; requestAttention(): void { this.parentChildService.requestAttention(this.message, this.id); } constructor(private parentChildService: ParentChildService) { this.subscription = parentChildService.attentionRequested$.subscribe((request, id) => { if (this.id != this.parentChildService.requestedBy) { this.siblingMessages.push(this.parentChildService.requestedBy + ": " + request); } }); } ngOnDestroy(): void { // prevent memory leak when component destroyed this.subscription.unsubscribe(); } }
parent-child.service.ts
import { Injectable } from '@angular/core'; import { Subject } from 'rxjs/Subject'; @Injectable() export class ParentChildService { // Observable sources private requestAttentionSource = new Subject<string>(); // Observable streams attentionRequested$ = this.requestAttentionSource.asObservable(); requestedBy: number; requestAttention(request: string, id: number) { this.requestedBy = id; this.requestAttentionSource.next(request); } }
The gist demonstrates the same thing.