2016-11-19 4 views
1

Ich habe eine Direktive, die ein Untermenü bei Klick öffnet, aber ich möchte es nur durch den Klick auf Dokumentenklick zu verbessern, wenn das Zielelement angeklickt wurde. Die Frage ist also, diese Direktive zu verbessern oder Host-Listener dynamisch hinzuzufügen.Angular 2 dynamisch Host-Listener in Direktiven hinzufügen

import { Directive, HostListener, Input, AfterContentInit, ElementRef, ViewContainerRef, ContentChild } from '@angular/core'; 

@Directive({ 
    selector: '[appSubMenu]' 
}) 

export class SubMenuDirective implements AfterContentInit { 
    private visible: boolean = false; 
    @ContentChild('subMenu') child: ElementRef; 

    constructor(private vcRef: ViewContainerRef) { } 

    ngAfterContentInit() { 
     this.child.nativeElement.style.display = 'none'; 
    } 

    @HostListener('document:click', ['$event', '$event.target']) 
    show(event:MouseEvent, targetElem: HTMLElement): void { 
     if (this.vcRef.element.nativeElement === targetElem && !this.visible) { 
      this.child.nativeElement.style.display = 'block'; 
      this.visible = true; 
     } else { 
      this.child.nativeElement.style.display = 'none'; 
      this.visible = false; 
     } 
    } 
} 

Antwort

5

Sie können die Renderer-Klasse verwenden, um dynamische Ereignisbindungen zu erzielen. Es gibt zwei Funktionen:

  • listen: Um Ereignisse von einem Element zu hören
  • listenGlobal: auf globale Ereignisse zu hören z.B. Dokument, Körper

Also in Ihrem Fall ist es wie folgt aussehen würde:

import { Directive, HostListener, Input, AfterContentInit, ElementRef, ViewContainerRef, ContentChild } from '@angular/core'; 

@Directive({ 
    selector: '[appSubMenu]' 
}) 

export class SubMenuDirective implements AfterContentInit { 
    private visible: boolean = false; 
    private unregister: Function; 
    @ContentChild('subMenu') child: ElementRef; 

    constructor(private vcRef: ViewContainerRef, private renderer: Renderer) { } 

    ngAfterContentInit() { 
     this.child.nativeElement.style.display = 'none'; 
    } 


    @HostListener('click', ['$event']) 
    elementClicked(event: MouseEvent) { 
     this.visible = !this.visible; 
     if (this.visible) { 
      this.unregister = this.renderer.listenGlobal('document', 'click',() => { 
       this.child.nativeElement.style.display = 'none'; 
       this.unregister(); 
      }); 
     } else { 
      this.child.nativeElement.style.display = 'block'; 
     } 
    } 
} 
Verwandte Themen