Created
January 20, 2018 10:36
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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