EventEmitter
We can use event emitter with service to achieve cross components communication. Assume we have two components called servers
and another
, and a service called data
We want to emit a signal when the buttons on servers
is clicked, and the another
component to received it.
The concept is like the listener pattern in Java.
data.service.ts
We create a EventEmitter in the service by EventEmitter<…>. The emitter can take any object, and can even be your own object. And we use number here.
import {EventEmitter, Injectable} from '@angular/core'; @Injectable({ providedIn: 'root' }) export class DataService { dataEmitter:EventEmitter<number>; constructor() { this.dataEmitter = new EventEmitter<number>(); } }
servers.component.html
Just some button that call its component core function when clicked.
<div style="background: lightgreen"> <button (click)="onButtonClicked(1)">1</button> <button (click)="onButtonClicked(2)">2</button> <button (click)="onButtonClicked(3)">3</button> <button (click)="onButtonClicked(4)">4</button> <button (click)="onButtonClicked(5)">5</button> </div>
servers.component.ts
We call the server emitter when the button in the UI is clicked. this.dataService.dataEmitter.emit(number);
will emit the event to whoever subscribed it.
import {Component, OnInit} from '@angular/core'; import {DataService} from "../data.service"; @Component({ selector: 'app-servers', templateUrl: './servers.component.html', styleUrls: ['./servers.component.css'] }) export class ServersComponent implements OnInit { constructor(private dataService: DataService) { } ngOnInit() { } onButtonClicked(number: number) { this.dataService.dataEmitter.emit(number); } }
another.component.html
Just display the variable value
of its component.
<div style="background: palevioletred"> <p>{{value}}</p> </div>
another.component.ts
The interesting thing here is onInit method. We subscribe the event emitter of the service. So whenever the emit() function is called, the callback function in subscibe(…) will be called. Here we have a number as parameter because we have set so in our data
service, and the value is passed from our servers
component.
One import thing we MUST UNSUBSCRIBE the emitter, when we are no longer use it, or else there will be memory leakage in your program.
import {Component, OnDestroy, OnInit} from '@angular/core'; import {DataService} from "../data.service"; @Component({ selector: 'app-another', templateUrl: './another.component.html', styleUrls: ['./another.component.css'] }) export class AnotherComponent implements OnInit, OnDestroy { value: number = 0; constructor(private dataService: DataService) { } ngOnInit() { this.dataService.dataEmitter .subscribe( (i: number) => { this.value = i; } ) } ngOnDestroy(): void { this.dataService.dataEmitter.unsubscribe(); } }