2016-07-04 2 views
1

Я работаю над приложением с большим количеством выпадающих списков, я хотел бы иметь возможность закрыть выпадающий список, когда клик происходит за пределами этого.Угловое: Обнаружение события щелчка внутри div с ngFor внутри

Я нашел несколько хороших решений, но ни один из них не обрабатывал случай наличия ngFor в нем, когда я регистрирую цель события click в ngFor, я получаю элемент, но у этого нет родителя. Я не могу обнаружить его с помощью «find» или «contains».

У кого-нибудь есть решение определить, является ли эта цель частью раскрывающегося списка?

директива

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

Пример где я назвать директиву

<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 (ток); возвращает мне две строки

<span>Item</span> 


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

Можете ли вы также опубликовать часть своего кода? – dfsq

+0

Я не понимаю, в чем проблема. В Angular2 нет виртуального DOM. –

+0

Проблема заключается в том, что я не могу сказать, произошел ли щелчок в this._el.nativeElement или нет. Contains(), find() и parentNode не работают, когда вы нажимаете на элемент ngFor. – 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

Нет, извините, но он не работает в моем случае, содержит() не обнаруживает все, что я нажимаю в моем 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()' делать то, что вы хотите. –

Смежные вопросы