Search code examples
javascriptangularrxjsngx-bootstrapngx-datatable

Implementing a @hostListener only when component is called


Angular application that uses a ngx-datatable. This table auto populates its [rows]. Within these rows is an [action] that displays a popup of items. This popup is a seperate component away from the table. I am calling the popup from the table in a parent > child link e.g.

<ngx-datatable-column name="Actions">
<ng-template let-row="row" ngx-datatable-cell-template>
    <app-actions-pop-up [actions]="row.actions"></app-actions-pop-up>
</ng-template>
</ngx-datatable-column>

This calls the action popup component. I have an @HostListener that listens to the clicks on the page for an Event. This then returns true/false to open or close the popup.

This is costly as my application will have 1000's of rows and it will impact the rendering as a click is being listened too regardless of whether the actions button is being clicked on.

e.g. if there are 4 row items, it will loop through 4 times. Imagine if there were 1000s of rows.

There is a lovely solution found here: Detect click outside Angular component where by it adds a @Hostlistener() to the document click event only once inside the popup component. The event should push the value of the clicked target element inside a public subject stored in a global utility service.

However, I have struggled to implement this thus far in my setup. Any help would be appreciated here - stackBlitz example


Solution

  • I would suggest simply adding (document:click)="clickout($event)" on your popup container.

    html

    <div *ngIf="isActive" (document:click)="clickout($event)" class="actions__container">
    

    ts

    clickout(event) {
      this.isActive = this.eRef.nativeElement.contains(event.target);
    }
    

    Angular will subscribe to that event only in case if popup is open and unsubscribe when it's closed. So you will have zero or only one subscription.

    You can also read one of my article regarding this optimization

    Forked Stackblitz