2016-07-04 39 views
1

我正在處理一個具有大量下拉菜單的應用程序,我希望能夠在發生點擊時發生點擊時關閉下拉菜單。Angular:使用ngFor檢測div內的單擊事件

我發現了一些很好的解決方案,但是他們都沒有處理在其中有ngFor的情況,當我在ngFor中記錄單擊事件目標時,我得到了元素,但是這個元素沒有任何父元素。我無法用'find'或'contains'來檢測它。

有人有解決方案來檢測此目標是否是下拉列表的一部分?

指令,其中我調用指令

<div (clickOutside)="onClickedOutside($event)"> 
      <ul> 
       <li *ngFor="let item of itemsList" (click)="selectItem(item)"> 
        <span class="item"> 
        {{item.name}} 
        </span> 
       </li> 
      </ul> 
     </div> 

當我點擊item.name,執行console.log(電流)

import { 
Directive, 
ElementRef, 
EventEmitter, 
Input, 
OnInit, 
Output, 
SimpleChange 
} from '@angular/core'; 

@Directive({selector: '[clickOutside]'}) 
export class ClickOutside implements OnInit { 
@Output() clickOutside:EventEmitter<Event> = new EventEmitter<Event>(); 

constructor(private _el:ElementRef) { 
    this.onClickBody = this.onClickBody.bind(this); 
} 

ngOnInit() { 
    document.body.addEventListener('click', this.onClickBody); 
} 

private onClickBody(e:Event) { 
    if (!this.isClickInElement(e)) { 
     this.clickOutside.emit(e); 
    } 
} 

private isClickInElement(e:any):boolean { 
    var current = e.target; 
    do { 
     console.log(current); 
     if (current === this._el.nativeElement) { 
      return(true); 
     } 
     current = current.parentNode; 
    } while (current); 
    return false; 
} 
} 

實施例;返回我的兩行

<span>Item</span> 


<li> 
    <span>Item</span> 
</li> 
+0

你還可以發佈一些你的代碼嗎? – dfsq

+0

我不明白問題所在。 Angular2中沒有虛擬DOM。 –

+0

問題是我無法確定點擊是否發生在this._el.nativeElement中。當你點擊一個ngFor項時,Contains(),find()和parentNode不起作用。 – ThomasP1988

回答

1
@Directive({selector: '[clickOutside]'}) 
export class ClickOutside implements OnInit { 
    @Output() clickOutside:EventEmitter<Event> = new EventEmitter<Event>(); 

    constructor(private _eref: ElementRef) { } 

    @HostListener('window:click') 
    private onClickBody(e:Event) { 
    if (!this.isClickInElement(e)) { 
     this.clickOutside.emit(e); 
    } 
    } 

    private isClickInElement(e:any):boolean { 
    return this._eref.nativeElement.contains(event.target); 
    } 
} 

又見https://stackoverflow.com/a/35713421/217408

+0

不,抱歉,但它不適用於我的情況,contains()不檢測我點擊我的ngFor的所有內容 – ThomasP1988

+0

我不喜歡在你的問題中看不到'ngFor'。 –

+0

這是否意味着你可以使它與'contains()'一起工作? –

1

該解決方案可與Chrome,但遺憾的是沒有與IE瀏覽器。我仍然在尋找另一種方式來做到這一點

private isClickInElement(e:any):boolean { 
    var current = e.target; 
    if(current == this._el.nativeElement) { 
     return true; 
    } 
    for(let parentKey in e.path) { 
     if(e.path[parentKey] == this._el.nativeElement) { 
      return true; 
     } 
    } 

    return false; 
} 
+0

這與虛擬DOM或'* ngFor'有什麼關係?什麼是IE版本? 「不適用於IE」意味着什麼? –

+0

對於虛擬DOM我不確定,這就是爲什麼我把一個問號,但謝謝你的信息。 IE11,似乎event.path不可用是每個瀏覽器。 – ThomasP1988

+0

'contains()'怎麼辦?我沒有看到任何會阻止'contains()'做你想要的東西的特別東西。 –