From 08eebaba360a4305f1bf5611c2615ad24331cff5 Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Mon, 28 Aug 2017 16:30:35 +0100 Subject: [PATCH] perf: lazily initialise event handlers Closes #52 --- src/confirmationPopover.directive.ts | 35 +++++++++++------------ test/angular-confirmation-popover.spec.ts | 5 ++++ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/confirmationPopover.directive.ts b/src/confirmationPopover.directive.ts index a52c949..76b3998 100644 --- a/src/confirmationPopover.directive.ts +++ b/src/confirmationPopover.directive.ts @@ -170,6 +170,11 @@ export class ConfirmationPopover implements OnDestroy, OnChanges, OnInit { */ popover: ComponentRef = null; + /** + * @private + */ + eventListeners: Function[] = []; + /** * @private */ @@ -226,18 +231,6 @@ export class ConfirmationPopover implements OnDestroy, OnChanges, OnInit { this.hidePopover(); } - /** - * @private - */ - @HostListener('document:click', ['$event.target']) - @HostListener('document:touchend', ['$event.target']) - onDocumentClick(target: HTMLElement): void { - - if (this.popover && !this.elm.nativeElement.contains(target) && !this.popover.location.nativeElement.contains(target)) { - this.hidePopover(); - } - } - /** * @private */ @@ -250,17 +243,21 @@ export class ConfirmationPopover implements OnDestroy, OnChanges, OnInit { } } - /** - * @private - */ - @HostListener('window:resize') - onResize(): void { - this.positionPopover(); + private onDocumentClick(event: Event): void { + if (this.popover && !this.elm.nativeElement.contains(event.target) && !this.popover.location.nativeElement.contains(event.target)) { + this.hidePopover(); + } } private showPopover(): void { if (!this.popover && !this.isDisabled) { + this.eventListeners = [ + this.renderer.listen('document', 'click', (event: Event) => this.onDocumentClick(event)), + this.renderer.listen('document', 'touchend', (event: Event) => this.onDocumentClick(event)), + this.renderer.listen('window', 'resize', () => this.positionPopover()) + ]; + const options: ConfirmationPopoverWindowOptions = new ConfirmationPopoverWindowOptions(); Object.assign(options, this.defaultOptions, { title: this.title, @@ -330,6 +327,8 @@ export class ConfirmationPopover implements OnDestroy, OnChanges, OnInit { this.popover.destroy(); this.popover = null; this.isOpenChange.emit(false); + this.eventListeners.forEach(fn => fn()); + this.eventListeners = []; } } diff --git a/test/angular-confirmation-popover.spec.ts b/test/angular-confirmation-popover.spec.ts index 27539e4..5880afc 100644 --- a/test/angular-confirmation-popover.spec.ts +++ b/test/angular-confirmation-popover.spec.ts @@ -228,6 +228,11 @@ describe('bootstrap confirm', () => { it('should re-position the popover when the window resizes', () => { const fixture: ComponentFixture = TestBed.createComponent(TestCmp); fixture.detectChanges(); + fixture.componentInstance.focusButton = 'confirm'; + fixture.detectChanges(); + clickFixture(fixture); + const popover: ComponentRef = fixture.componentInstance.confirm.popover; + popover.changeDetectorRef.detectChanges(); const positionPopover: sinon.SinonSpy = sinon.spy(fixture.componentInstance.confirm as any, 'positionPopover'); window.dispatchEvent(new Event('resize')); expect(positionPopover).to.have.been.calledOnce;