Communicate with Angular components outside of Angular
Last updated
Was this helpful?
Last updated
Was this helpful?
import {Injectable, NgZone} from "@angular/core";
/**
* Service that allows Angular components to receive and fire
* events from outside
*
* Usage from outside of Angular:
* window.fireAngularEvent('sampleEventName', args)
* window.subscribeToAngularEvent('sampleEventName', fn)
*
* Usage from Angular component:
* globalPubSub.fireEvent('sampleEventName', args)
* globalPubSub.subscribe('sampleEventName', fn, context)
*/
@Injectable()
export class GlobalPubSub {
allowedEvents = [
"sampleEventName",
"sampleEventName2"
];
private subscriptions : {[key:string]:Function[];} = {};
private subscriptionContext : {[key:string]:any;} = {};
constructor(private zone: NgZone) {
this.allowedEvents.forEach((eventName) => {
this.subscriptions[eventName] = []
});
window['fireAngularEvent'] = (eventName, args) => {
if (!this.subscriptions[eventName]) {
throw new Error('Event has to be defined in the event list.')
}
zone.run(() => {
this.fireEvent(eventName, args);
});
};
window['subscribeToAngularEvent'] = (eventName, fn) => {
this.subscribe(eventName, fn);
};
}
subscribe(eventName: string, fn: Function, context: any) {
if (!this.subscriptions[eventName]) {
throw new Error('Event has to be defined in the event list.');
}
if(context){
this.subscriptionContext[eventName]=context;
}
this.subscriptions[eventName].push(fn);
}
fireEvent(eventName: string, args) {
if (!this.subscriptions[eventName]) {
throw new Error('Event has to be defined in the event list.');
}
let context = this.subscriptionContext[eventName];
this.subscriptions[eventName].forEach((fn) => {
if (context){
fn.apply(context, args);
}else{
fn.apply(null, args);
}
});
}
}
JavaScript Side calling script
// call angular component subscription
function showPreview(event, docIndex){
var args = [];
args.push(event);
args.push(docIndex);
event.stopPropagation();
window.fireAngularEvent('angular.message-thread-tab.showPreview', args);
}
Angular Html code
return attachmentPrex + ' <span id="attachmentDiv" class="attachment-highlight" onmouseenter="showPreview(event,'+docIndex+')">' + matched +'</span>';
Angular Side Event Subscribe Client Code
// Init event service in Component
constructor(private globalEventService : GlobalEventService,public dialog: MatDialog) {
// subscript globalEvent
this.globalEventService.subscribe("angular.message-thread-tab.showPreview", this.showPreview, this);
this.globalEventService.subscribe("angular.message-thread-tab.hidePreview", this.hidePreview, this);
this.globalEventService.subscribe("angular.message-thread-tab.showAttachment", this.showAttachment, this);
}