Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using HostListener in a structural directive

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?

like image 747
Ofer Herman Avatar asked Sep 02 '16 14:09

Ofer Herman


People also ask

Is Ngfor structural directive?

Structural directives are directives which change the DOM layout by adding and removing DOM elements. Angular provides a set of built-in structural directives (such as NgIf , NgForOf , NgSwitch and others) which are commonly used in all Angular projects.

What is the use of HostListener?

HostListenerlink Decorator that declares a DOM event to listen for, and provides a handler method to run when that event occurs.

What is the difference between HostBinding and HostListener?

Introduction. @HostBinding and @HostListener are two decorators in Angular that can be really useful in custom directives. @HostBinding lets you set properties on the element or component that hosts the directive, and @HostListener lets you listen for events on the host element or component.

What are the purpose of HostListener decorators and the?

We use the HostListner decorator to decorate functions onMouseOver & onMouseLeave . We apply the directive on a host element ( p in the example) as shown below. Whenever the mouse is moved over the p element, the mouseover event is captured by the HostListener.


1 Answers

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

Plunker

like image 158
yurzui Avatar answered Oct 30 '22 02:10

yurzui