2016-02-04 7 views
6

Ho un div che voglio mostrare/nascondere su messa a fuoco/sfocatura di uno input. Ecco una versione semplificata di quello che sto cercando:Il menu a discesa di Angular2 roll-my-own si nasconde se si fa clic di distanza?

<input (focus)="ShowDropDown=true;" (blur)="ShowDropDown=false;" /> 
<div *ngIf="ShowDropDown"> 
    <ul> 
    <li (click)="...">...</li> 
    <li (click)="...">...</li> 
    <li (click)="...">...</li> 
    </ul> 
</div> 

Questo div contiene un elenco di elementi su cui cliccare. Il mio problema è che la sfocatura dello input si verifica prima del clic di li.

Voglio mantenere le cose semplici. Non voglio impostare l'attivazione di tutto o fare clic sull'evento per impostare ShowDropDown=false ma è necessario mantenere aperto il divario per l'interazione.

Potrei avere ShowDropDown essere un numero in cui la messa a fuoco aggiunge 1 ad esso, il mouse sul div aggiunge un altro 1 ad esso, sfocando l'input sottrae 1 e il mouse fuori dalle div sottrai 1 ma immagino che possa uscire da sincronizza davvero facilmente.

C'è un modo più semplice per farlo? Posso forzare la sfocatura a correre dopo il clic?

risposta

6

ho trovato la risposta a this question: il mousedown avverrà prima della sfocatura, ma il clic avverrà dopo. Ho semplicemente cambiare per

<input (focus)="ShowDropDown=true;" (blur)="ShowDropDown=false;" /> 
<div *ngIf="ShowDropDown"> 
    <ul> 
    <li (mousedown)="...">...</li> 
    <li (mousedown)="...">...</li> 
    <li (mousedown)="...">...</li> 
    </ul> 
</div> 

Questo mi dà l'ordine degli eventi che voglio senza fare ritardi o "reference counting", dove il mouse è o l'aggiunta di un evento click per tutto il resto del DOM.

1

Aggiornamento

Un modo migliore per ascoltare gli eventi globali è

@Comonent({... 
    host: {'(window:click)': 'clickHandler()'} 
}) 

originale

Basta verificare se il clic è all'interno o all'esterno discesa:

import {DOM} from angular2/platform/common_dom; 

constructor(private elementRef: ElementRef) { 
    DOM.getGlobalEventTarget('window') 
    .addEventListener('click', (event) => { 
     // check if event.target is a child of elementRef.nativeElement 
     // if not hide the dialog 
    }); 
} 

Attualmente non posso fare questo lavoro in TS anche se DOM è sempre indefinito.
Questo funziona bene in Dart.
Plunker

ho creato un problema https://github.com/angular/angular/issues/6904

0

riesco a pensare a un semplice trucco come questo

<input (focus)="ShowDropDown=true;" (blur)="ShowDropDown=false;" /> 
<div *ngIf="ShowDropDown"> 
    <ul> 
    <li (click)="...; ShowDropDown = true">...</li> 
    <li (click)="...; ShowDropDown = true">...</li> 
    <li (click)="...; ShowDropDown = true">...</li> 
    </ul> 
</div> 

Non è la soluzione più elegante, ma dovrebbe funzionare

+0

I miei eventi click negli elementi li non sono affatto in esecuzione o non avrei bisogno di un lavoro in giro. La sfocatura avviene prima, imposta ShowDropDown su false, il div è nascosto, i clic si registrano sull'elemento dietro il div. –

Problemi correlati