Skip to content

Commit

Permalink
fix: do not use document click HostListener
Browse files Browse the repository at this point in the history
HostListener on document click should not be used because it triggers change detection when it is not needed
  • Loading branch information
anjmao committed Sep 30, 2017
1 parent 4f93a5b commit 80b6aa2
Showing 1 changed file with 34 additions and 25 deletions.
59 changes: 34 additions & 25 deletions src/lib/src/ng-select.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
ViewChild,
ElementRef,
ChangeDetectionStrategy,
Optional
Optional,
Renderer2
} from '@angular/core';

import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
Expand Down Expand Up @@ -85,11 +86,15 @@ export class NgSelectComponent implements OnInit, OnDestroy, ControlValueAccesso
filterValue: string = null;

private propagateChange = (_: NgOption) => {};
private disposeDocumentClickListener = () => {};

constructor(@Optional() config: NgSelectConfig,
private changeDetectorRef: ChangeDetectorRef,
private elementRef: ElementRef) {
private elementRef: ElementRef,
private renderer: Renderer2
) {
this.mergeConfig(config);
this.handleDocumentClick();
}

@Input()
Expand All @@ -115,6 +120,7 @@ export class NgSelectComponent implements OnInit, OnDestroy, ControlValueAccesso

ngOnDestroy() {
this.changeDetectorRef.detach();
this.disposeDocumentClickListener();
}

@HostListener('keydown', ['$event'])
Expand Down Expand Up @@ -146,29 +152,6 @@ export class NgSelectComponent implements OnInit, OnDestroy, ControlValueAccesso
}
}

@HostListener('document:click', ['$event'])
handleDocumentClick($event) {
// prevent close if clicked on select
if (this.elementRef.nativeElement.contains($event.target)) {
return;
}

// prevent close if clicked on dropdown menu
const dropdown = this.getDropdownMenu();
if (dropdown && dropdown.contains($event.target)
) {
return;
}

if (this.isFocused) {
this.onInputBlur($event);
}

if (this.isOpen) {
this.close();
}
}

handleArrowClick($event: Event) {
$event.stopPropagation();
if (this.isOpen) {
Expand Down Expand Up @@ -338,6 +321,32 @@ export class NgSelectComponent implements OnInit, OnDestroy, ControlValueAccesso
this.itemsList.markItem(item);
}

private handleDocumentClick() {
const handler = ($event) => {
// prevent close if clicked on select
if (this.elementRef.nativeElement.contains($event.target)) {
return;
}

// prevent close if clicked on dropdown menu
const dropdown = this.getDropdownMenu();
if (dropdown && dropdown.contains($event.target)
) {
return;
}

if (this.isFocused) {
this.onInputBlur($event);
}

if (this.isOpen) {
this.close();
}
};

this.disposeDocumentClickListener = this.renderer.listen('document', 'click', handler);
}

private validateWriteValue(value: any) {
if (value instanceof Object && this.bindValue) {
throw new Error('Binding object with bindValue is not allowed.')
Expand Down

0 comments on commit 80b6aa2

Please sign in to comment.