I have a directive which needs to listen for any event provided declaratively by the engineer. Here's an example:
import { Directive, Input, ElementRef, HostListener, OnInit } from '@angular/core';
//--
import { Sandbox } from '../../../sandbox';
@Directive({ selector: '[addItem]' })
class AddNewItemDirective implements OnInit {
@Input('addItem') data;
@Input() on: string = 'click';
constructor(private $: Sandbox, private element: ElementRef) { }
ngOnInit() { console.log('@INIT', this); }
@HostListener('click', ['$event']) handleEvent(e) {
console.log('add-item', e);
}
}
export { AddNewItemDirective };
Here's its usage:
<button class="btn btn-primary" [addItem]="{ name: 'Jeffrey' }" on="focus">Add New Item</button>
This works fine. However, my intuition told me I should be able to dynamically set the HostListener's arguments at render time based upon an input parameter:
@Directive({ selector: '[addItem]' })
class AddNewItemDirective implements OnInit {
@Input('addItem') data;
@Input() on: string = 'click';
constructor(private $: Sandbox, private element: ElementRef) { }
ngOnInit() { console.log('@INIT', this); }
@HostListener(this.on, ['$event']) handleEvent(e) {
console.log('add-item', e);
}
}
Of course, this.on
would not be overwritten with 'focus'
until the time ngOnInit
is invoked. To my surprise, this.on
throws an error because undefined has no property 'on'
. So when my directive class is instantiated, for whatever reason, this === undefined
.
I found one similar question here, though, its looking to dynamically modify HostListener at runtime while I just need it modified at compile/render/instantiation time.
Can someone please shed light on how I can accomplish this?
Thx
HostListener
is not dynamic, it can not be changed at runtime. You should use Renderer
class, which provides listen
method:
@Input()
public on:string;
private dispose:Function;
constructor(private renderer:Renderer, private elementRef:ElementRef){}
ngOnInit(){
this.dispose = this.renderer.listen(this.elementRef.nativeElement, this.on, e => console.log(e));
}
ngOnDestroy(){
this.dispose();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With