2016-11-19 6 views
1

私は、クリック時にサブメニューを開くディレクティブを持っていますが、ターゲット要素がクリックされたときにドキュメントをクリックするだけで改善したいと思います。ですから、このディレクティブを改善するか、ホストリスナーを動的に追加する方法です。角2は、ディレクティブに動的にホストリスナーを追加します

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

答えて

5

レンダラークラスを使用して、動的イベントバインディングを実現できます。

  • listen::二つの機能が存在する要素
  • listenGlobalからイベントをリッスンするには:例えばグローバルイベントをリッスンするには

    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'; 
         } 
        } 
    } 
    
    :それは次のようになり、あなたのケースで、ドキュメント、身体だから、

関連する問題