I would like to share some of the methods I have tried.
Lets first discuss the ways we can broadcast and listen events within application that I have tried first.
A) events broadcast-receive within application
1) With host
property of @componet
e.g
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"],
host: {
"(document:click)": "onDocumentClicked($event)"
}
})
export class AppComponent {
onDocumentClicked(ev) {
console.log("clicked", ev);
}
}
2) with @HostListener
import { HostListener, Component } from "@angular/core";
add function and listener as
@HostListener("document:click", ["$event"])
onDocumentClicked(ev) {
console.log("clicked", ev);
}
3) Observables
from rxjs
Create service as
import { Injectable } from '@angular/core';
import { from, Subject } from 'rxjs';
@Injectable()
export class ListnerAndBroadcast {
listeners: any;
eventsSubject: any;
events: any;
constructor() {
this.listeners = {};
this.eventsSubject = new Subject();
this.events = from(this.eventsSubject);
this.events.subscribe(
({name, args}) => {
if (this.listeners[name]) {
for (let listener of this.listeners[name]) {
listener(...args);
}
}
});
}
on(name, listener) {
if (!this.listeners[name]) {
this.listeners[name] = [];
}
this.listeners[name].push(listener);
}
off(name, listener) {
this.listeners[name] = this.listeners[name].filter(x => x != listener);
}
broadcast(name, ...args) {
this.eventsSubject.next({
name,
args
});
}
}
Now we need to broadcast event from any child component
this._ListnerAndBroadcast.broadcast('myCustomEvent', 'event');
In my case I have broadcasted the same from my deepest component footer.
and receiving it on root component as
this._ListnerAndBroadcast.on('myCustomEvent', (event) => {
console.log('myCustomEvent received '+ event);
});
Personally I like above approach as it can be dynamic and can handle any stream of events.
B) event received from third party or out of application
I have used Renderer2
as
In child component add as
import { Component, Renderer2 } from '@angular/core';
renderer2.listen('document', 'myCustomEvent', (evt) => {
console.log('getting it from renderer ', evt);
})
Now we need to broadcast event .
so to mimic third party events service , run following code in browsers console
var event = new CustomEvent(
'myCustomEvent',
{ detail: { 'param1': 1, 'param2': 2 } }
);
document.dispatchEvent(event);
You would be able to see the results in console .
I am using angular 7+ and rxjs 6.2
links helped me to learn just consolidated all the solution above
Global Events and Event Delegation
Global event listener with observable
Thanks !