43

How to use the host listener and host binding in angular 2? I tried like the below for host listener, but it's always showing a Declaration expected error.

app.component.ts:

import {Component, EventEmitter, HostListener, Directive} from 'angular2/core';

@Directive({
    selector: 'button[counting]'
})

class HostSample {
    public click = new EventEmitter();
    @HostListener('click', ['$event.target']);
    onClickBtn(btn){
        alert('host listener');
    }
}

@Component({
    selector: 'test',
    template: '<button counting></button>',
    directives: [HostSample]
})

export class AppComponent {
   constructor(){
   }
}
tobias47n9e
  • 2,233
  • 3
  • 28
  • 54
BhaRathi RajaMani
  • 439
  • 1
  • 4
  • 4

2 Answers2

85

@HostListener is a decorator for the callback/event handler method, so remove the ; at the end of this line:

@HostListener('click', ['$event.target']);

Here's a working plunker that I generated by copying the code from the API docs, but I put the onClick() method on the same line for clarity:

import {Component, HostListener, Directive} from 'angular2/core';

@Directive({selector: 'button[counting]'})
class CountClicks {
  numberOfClicks = 0;
  @HostListener('click', ['$event.target']) onClick(btn) {
    console.log("button", btn, "number of clicks:", this.numberOfClicks++);
  }
}
@Component({
  selector: 'my-app',
  template: `<button counting>Increment</button>`,
  directives: [CountClicks]
})
export class AppComponent {
  constructor() { console.clear(); }
}

Host binding can also be used to listen to global events:

To listen to global events, a target must be added to the event name. The target can be window, document or body (reference)

@HostListener('document:keyup', ['$event'])
handleKeyboardEvent(kbdEvent: KeyboardEvent) { ... }
tobias47n9e
  • 2,233
  • 3
  • 28
  • 54
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • Thank you Mark. Now I found my mistake. I used semicolon at the end in this line -> @HostListener('click', ['$event.target']); this produced declaration expected error. – BhaRathi RajaMani Jan 12 '16 at 05:56
  • I'm doing this with a 'blur' event, and it works in Chrome but not IE 11. I'm using angular2 beta.8 right now. Error from angular polyfills: `EXCEPTION: Error during evaluation of "blur" ORIGINAL EXCEPTION: TypeError: Object doesn't support this action`. I can open a new question if you haven't seen this before, but I'll likely have to upgrade to the rc soon. – ps2goat May 04 '16 at 21:53
  • the example in plunker is nice; and i understand the decorator HostListener. It's possible omit this decorator just to do a button counter? i mean in the component just with a (click) = function() ... , I mean is not more clear than this case just do it with that decorator? – stackdave Aug 26 '16 at 23:14
  • Can you update the link to reference? That page is no longer there. – Sam Sep 21 '16 at 17:35
  • @SagarDesai, they've changed the API docs around so much lately... and it doesn't look like that comment is shown in the API docs anymore. Here's a direct link to the code comment though: https://github.com/angular/angular/blob/42f60ca303543cb3a869a6b42bbcd5890b09f131/modules/%40angular/core/src/metadata/directives.ts#L219 – Mark Rajcok Sep 21 '16 at 20:14
  • @MarkRajcok What should be a `Directive` `selector`, if it's sole purpose to add a global event handler like `document:keyup`? – Alexander Abakumov Oct 16 '18 at 15:36
  • I avoid the `directives` property right? Otherwise: `"Object literal may only specify known properties, and 'directives' does not exist in type 'Component'.ts(2345)"` I guess I could use the `Declarations` property on the module instead? – Nate Anderson Dec 29 '18 at 19:56
17

This is the simple example to use both of them:

import {
  Directive, HostListener, HostBinding
}
from '@angular/core';

@Directive({
  selector: '[Highlight]'
})
export class HighlightDirective {
  @HostListener('mouseenter') mouseover() {
    this.backgroundColor = 'green';
  };

  @HostListener('mouseleave') mouseleave() {
    this.backgroundColor = 'white';
  }

  @HostBinding('style.backgroundColor') get setColor() {
     return this.backgroundColor;
  };

  private backgroundColor = 'white';
  constructor() {}

}

Introduction:

  1. HostListener can bind an event to the element.

  2. HostBinding can bind a style to the element.

  3. this is directive, so we can use it for

    Some Text
  4. So according to the debug, we can find that this div has been binded style = "background-color:white"

    Some Text
  5. we also can find that EventListener of this div has two event: mouseenter and mouseleave. So when we move the mouse into the div, the colour will become green, mouse leave, the colour will become white.

tobias47n9e
  • 2,233
  • 3
  • 28
  • 54
Xin Meng
  • 1,982
  • 3
  • 20
  • 32