Skip to content

Instantly share code, notes, and snippets.

@devoto13
Created January 20, 2018 10:36
Show Gist options
  • Save devoto13/a1663506728212481cdb4f301002b1d4 to your computer and use it in GitHub Desktop.
Save devoto13/a1663506728212481cdb4f301002b1d4 to your computer and use it in GitHub Desktop.
EventManager, which allows to subscribe to any event outside of NgZone, so event won't trigger change detection
/**
* Custom event manager, which allows to add event listeners outside of Angular
* zone.
*
* See https://stackoverflow.com/a/45229997/1377864 for original idea
*/
@Injectable()
export class CustomEventManager extends EventManager {
addGlobalEventListener(target: string, eventName: string, handler: Function): Function {
if (eventName.endsWith(NO_ZONE)) {
eventName = eventName.slice(0, -NO_ZONE.length);
return this.getZone().runOutsideAngular(() => super.addGlobalEventListener(target, eventName, handler));
}
return super.addGlobalEventListener(target, eventName, handler);
}
addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
if (eventName.endsWith(NO_ZONE)) {
eventName = eventName.slice(0, -NO_ZONE.length);
return this.getZone().runOutsideAngular(() => super.addEventListener(element, eventName, handler));
}
return super.addEventListener(element, eventName, handler);
}
}
/**
* Suffix, which will cause event listener to be added outside of Angular zone
* and therefore change detection won't be triggered after event fires. It is
* useful, when event should not trigger change detection run every time and
* event is fired very often thus causing performance issues.
*
* This should be appended as suffix to event name and is supported for all
* event listeners managed by Angular.
*
* @example
*
* component MyComponent {
* background = 'white';
*
* @HostListener('mouseover' + NO_ZONE)
* onMouseOver() {
* if (someCondition) {
* this.background = 'red';
* this.changeDetector.detectChanges();
* }
* }
* }
*
* @type {string}
*/
export const NO_ZONE = '.no-zone';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment