在结构指令中使用 HostListener

using HostListener in a structural directive

我有一个结构指令,它需要像在属性指令上那样监听主机上的事件。

在指令中使用@HostListener没有错误,但没有收到任何事件。

指令代码如下:

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();
    }
}
}

和模板:

<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>

还有一个plunker example

问题是是否可以在结构指令中使用 @HostListener

@HostListener 有效,但它应用于评论 html 标签,例如:

<!--template bindings={
  "ng-reflect-my-unless": "true"
}-->

您可以尝试以下解决方法:

@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();
    }
  }
}

Plunker