2017-12-07 135 views
6

Próbuję utworzyć dyrektywę dla rozwijanej listy, o ile pracuję z pojedynczą, działa jak charm. Widzę kliknięcie poza zakresem, używając następującego kodu:Zamknij listę rozwijaną, gdy drugi jest otwierany/document.click zablokowany przez kliknięcie Angular 5

@HostListener('document:click', ['$event']) 
    onDocumentClick(event: any): void { 
    console.log("document click"); 
    // close 
} 
@HostListener('click') 
    onClick(): void { 
    console.log('click on '); 
    // toggle 
    } 

Problem występuje, gdy utworzono 2 rozwijane listy rozwijane. Chciałbym zamknąć pierwsze menu po drugim uruchomieniu, jednak gdy kliknę na drugie menu, uruchamiane jest tylko zdarzenie "kliknięcie", a "document.click" nie jest wykonywane. Spodziewam się, że oba zdarzenia powinny wystąpić, chyba że jawnie użyję preventDefault przy kliknięciu, ale najwyraźniej dzieje się to automatycznie.

Jakie powinno być prawidłowe podejście w ustawieniu kątowym 5, aby zamknąć pierwsze menu rozwijane, gdy drugi jest otwarty?

Odpowiedz

0

Może spróbuj coś takiego:

@HostListener('document:click', ['$event']) 
    onClick(event) { 
    if(this.eRef.nativeElement.contains(event.target)) { 
     // toggle logic 
    } else { 
     // close logic 
    } 
} 

Więc zamiast dwóch zdarzeń sprzecznych ze sobą można mieć jedno zdarzenie z dwoma kawałkami logiki obsłużyć dokładnie to, czego potrzebujesz w zależności po kliknięciu wewnątrz lub poza samym elementem. Ma sens?

ta została podjęta z here

+0

Dzięki ale "wewnątrz click" nie zostanie wyzwolony”-> if (this._element.nativeElement.contains (event.target)) { console.log ("kliknij"); } nie działa –

+0

Czy masz błędy lub po prostu nie dostaniesz się do wnętrza, jeśli? –

+0

Brak błędów, po prostu nie dostaję się do wnętrza –

0

Jak o tworzeniu dyrektywy, które można wykorzystać wszędzie?

@Directive({ 
    selector : '[clicked-outside]' , 
    host  : { 
     '(document:click)' : 'onClick($event)', 
     '(document:touch)' : 'onClick($event)', 
     '(document:touchstart)' : 'onClick($event)' 
    } 
}) 
export class ClickedOutsideDirective { 
    @Input('clicked-outside') callback : Function; 

    constructor (private _el : ElementRef) { 
    } 

    private onClick (event : any) { 
     if (this.clickedOutside(event)) { 
      if (this.callback) { 
       this.callback(); 
      } 
     } 
    } 

    private clickedOutside (event : any) { 
     let clickedTarget = event.target; 
     let host   = this._el.nativeElement; 
     do { 
      if (clickedTarget === host) { 
       return false; 
      } 
      clickedTarget = clickedTarget.parentNode; 
     } while (clickedTarget); 
     return true; 
    } 
} 

i można go używać tak:

@Component({ 
    selector:'your-dropdown', 
    template:` 
     <div class="your-dropdown-top-most-wrapper" [clicked-outside]="onClickOutSide"></div> 

    ` 
}) 
export class YouDropdownComponent{ 


    public onClickOutSide =()=>{ 


     this.closeMyDropdown()// this is your function that closes the dropdown 
    } 
}