1

To explain what I'm looking for it's best illustrated the way jQuery works where you can specify a generic HTML element to watch for events:

$("label").on("click", function(event){ 
    // do stuff to this element
});

Or a traditional addEventListener

document.getElementsByTagName('label').addEventListener('click', function(event){
    // do stuff to this element
});

I'm surprised to not see this solution all over the internet and instead I see lots of examples on how to use event binding (click)="clickHandler" Obviously you wouldn't want to place that handler all over your view.

Can I get some direction/links on how to watch generic events in Angular?

UPDATE: I appreciate the debate between @HostListener listening to the entire DOM, Renderer2 which will work for specific general elements and apparently the Observable option as well.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ben Racicot
  • 5,332
  • 12
  • 66
  • 130
  • 2
    are you looking to attach events dynamically? or do you just prefer to attach events on the JS side? personally, I think the event binding notation in angular's template syntax: `(event)` is clear and cleaner than doing all the work on the JS side. anyway, you can find what you're looking for here: http://stackoverflow.com/questions/35080387/dynamically-add-event-listener-in-angular-2 – Ahmed Musallam May 16 '17 at 18:26
  • Maybe if you use the same handler at different place, you can try to make a component – runit May 16 '17 at 18:29
  • Hey @AhmedMusallam it seems wrong to apply event binding 20+ times in my view. But `Renderer` looks like the answer, thanks! – Ben Racicot May 16 '17 at 18:29
  • Possible duplicate of [Dynamically add event listener in Angular 2](http://stackoverflow.com/questions/35080387/dynamically-add-event-listener-in-angular-2) – Ahmed Musallam May 16 '17 at 18:31
  • It makes me wonder how big is the view for your component and if you should break it down. Anyway, if that's it, I flagged the question as a duplicate of the one I posted. – Ahmed Musallam May 16 '17 at 18:32

3 Answers3

1

The @Output format ((click)="") is Angular's wrapper for DOM events (e.g. the example would be for onclick). It's important because Angular manages change detection between child and parent components and uses these @Inputs and @Outputs to do so.

Angular does a lot to work with the DOM api itself and we shouldn't mess with it too much. A lot of times you could get away with a directive or an extended component to handle the behavior.

However, if you wanted to place something globally at runtime, you could inject the Renderer into your component:

constructor(public el: ElementRef, public renderer: Renderer) { 
   renderer.listenGlobal('document', 'click', (event) => {
     // Do something with 'event'
   });
}

Note: Renderer is marked as depreciated and will be replaced with Renderer2 with a slightly different API.

joh04667
  • 7,159
  • 27
  • 34
1

For a declarative solution if you want a single click handler for the whole document, put this in any component:

@HostListener('document:click', ['$event'])
onDocumentClick(event: MouseEvent) {
  console.log(event);
}
dbandstra
  • 1,304
  • 9
  • 10
  • nice, very interesting – Yeysides May 16 '17 at 18:48
  • I've seen this but like the concern of adding many event bindings, what are the implications of importing and using `@HostListener` which apparently listens to the the entire DOM or `Renderer2` which listens to a specific element? – Ben Racicot May 16 '17 at 18:52
  • HostListener attaches only one event listener (for each instance of the component you defined it in). If you want a single event listener for the whole app then put it in a component that only exists once, such as the AppComponent. I think my answer is equivalent to joh04667's answer except that it's a more declarative style. – dbandstra May 16 '17 at 19:06
0

You can use Rxjs observables and subscribe to dom events:

var button = document.querySelector('button')

Rx.Observable.fromEvent(button, 'click')
  .subscribe(
    (event) => console.log(event)
   )
Yeysides
  • 1,262
  • 1
  • 17
  • 27
  • 2
    probably not a good idea to recommend adding events or even doing `document.querySelector` unless there is a certain circumstance and that code is in the `AftreViewInit` component lifesycle. – Ahmed Musallam May 16 '17 at 18:34
  • it's the same thing as referrer with the added benefit of observables – Yeysides May 16 '17 at 19:27
  • 1
    I'm so tired of Rxjs. It's like using regular expressions. You use it to solve a problem, and then you have two problems. – Reactgular May 16 '17 at 19:59
  • @ThinkingMedia lol it def seems that way at first and has a massive learning "cliff" but it's worth it imho. – Yeysides May 16 '17 at 20:00