Global Events and Event Delegation in Angular 2

In Angular 2, we are used to listening for events on the Component’s DOM elements, however how do we listen to events outside of this range?

Two ways to do this:

  1. Creating a Host Listener
  2. Using the Component’s host property

The Host Listener Way

Angular 2 provides a HostListener Decorator in order to match an event triggered on a target with a function declared on the next line.
Just like this:

The syntax is as follow: ‘target:event’,  [args].
When clicking on the document, we will be able to use the event triggered, you can also pass other arguments like $event.target for example.
However the target must be global, if you prefer, you can replace document by window.

The Host Way

Angular 2 Components provide a host property in order to match a function with an event triggered on a target.

The syntax is as follow: (‘target:event)’: ‘function(args)’.
Same mechanism as the HostListener, only global and configuration friendly.

Event Delegation

Now that we have more experience under our belt, we can tackle one very important JavaScript concept: Event Delegation.

I discovered this concept thanks to the Great David Walsh, head there for a quick 5-minutes read.

5 minutes later

So how do we do this in Angular 2?
Let’s start by using a similar template:

Notice the #ulEl?
It’s a reference that we will use in order to attach the listener in our Component here:

We get our ul Element and stock it as an ElementRef.
When we init our Component, we use the Renderer (for cross-platform compatibility) in order to attach an EventListener.
If the <ul> or a <li> tag is clicked, we trigger the logElement function.

This function will acquire the target from the event, if this target is a <li> tag we log the id property.

Subscribe to my mailing list to get access to a Free 7-day Ionic 3 introduction email course!
100% Privacy. I'll never spam you!

Conclusion

As usual many ways to do the work.
I prefer to go with the host property of a Component, this solution clearly lists every listener – target – function matching.
Event Delegation is an interesting trick that can help you for specific cases, it’s being discussed a lot in the community, some times as a savior (see the comments here) and on other cases just as a little plus (there).

11 Comments

  1. AndreySuperstar AndreySuperstar
    April 2, 2017    

    Awesome!

    • Matthieu Drula Matthieu Drula
      April 2, 2017    

      Thanks!

  2. AndreySuperstar AndreySuperstar
    April 2, 2017    

    Do we have to remove listener? How to do this?

    • Matthieu Drula Matthieu Drula
      April 2, 2017    

      Totally forgot about this part, nice comment.
      Has for host listeners no need to remove, only the renderer listener needs to be removed.
      I’ll add this part thanks!

  3. Brian Brian
    April 5, 2017    

    Hi

    I have a question regarding AOT compilation….

    The renderer option is needed when using AOT compilation – this.renderer.listen(this.ulEl.nativeElement, ‘click’, this.logElement);
    Does the HostListener approach work with AOT?
    @HostListener(‘document:clicked’, [‘$event’])

    • Matthieu Drula Matthieu Drula
      April 5, 2017    

      No issue on this side.
      I just corrected a typo:
      @HostListener(‘document:clicked’, [‘$event’])
      Should be:
      @HostListener(‘document:click’, [‘$event’])

      • Colin Colin
        April 5, 2017    

        Hi. Thanks, I just ran an example and it does work with AOT. It was actually server side rendering I was thinking about, but again, I don’t think this would matter

        • Matthieu Drula Matthieu Drula
          April 5, 2017    

          Yes Renderer is necessary for server-side rendering and also web sockets, it’s good to keep that in mind.

  4. April 23, 2017    

    Thanks for sharing Matthieu! Regarding the second example I think you can use a simpler approach by just using the (click) syntax on the ul element. If you need to intercept the click event on the li element you can do as well as event bubbling will take care of the rest.

Leave a Reply

Your email address will not be published. Required fields are marked *

1K Shares