Reputation: 3068
I have a structural directive in which it's needed to listen to events on the host like it's done on an attribute directive.
There is no error in using @HostListener
in the directive but no event is received.
Here is the directive code:
import { Directive, HostListener, Input } from '@angular/core';
import { TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({ selector: '[myUnless]' })
export class UnlessDirective {
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef
) { }
@HostListener("click", ["$event"]) public onClick(event: any) {
console.log("click", event);
}
@Input() set myUnless(condition: boolean) {
if (!condition) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
}
and the template:
<h1>Structural Directive with HostListener</h1>
<p *myUnless="condition">
condition is false and myUnless is true.
</p>
<p *myUnless="!condition">
condition is true and myUnless is false.
</p>
There's also a plunker example
The question is if it's possible to use @HostListener
in structural directives?
Upvotes: 10
Views: 4312
Reputation: 214175
@HostListener
works but it's applied to comment html tag like:
<!--template bindings={
"ng-reflect-my-unless": "true"
}-->
You can try the following workaround:
@Directive({ selector: '[myUnless]' })
export class UnlessDirective {
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private renderer: Renderer) { }
onClick(event: any) {
console.log("click", event);
}
@Input() set myUnless(condition: boolean) {
if (!condition) {
this.viewContainer.createEmbeddedView(this.templateRef);
const el = this.templateRef.elementRef.nativeElement.nextElementSibling;
this.renderer.listen(el, 'click', this.onClick);
} else {
this.viewContainer.clear();
}
}
}
Upvotes: 12