typescript - Angular 6 - anropa funktion vid klick ELLER fokus


Jag vill kunna anropa en funktion från en komponent bara vid klick ELLER fokus. Här är en del av komponentens HTML:

<div class="form-add-new__input-box">
     <input
           #commentCategories
           class="form-add-new__category-box"
           (click)="toggleCategoriesSelection($event)"
           (focus)="toggleCategoriesSelection($event)"
           (keyup)="searchCategory($event.target.value)"
           tabindex="0"
           placeholder="Search or select">
     <span class="icon-arrow-down"></span>
</div>

och funktionen:

public toggleCategoriesSelection(event: Event): void {
    event.stopPropagation();
    event.preventDefault();
    this.categoriesSelectOpen = !this.categoriesSelectOpen;
}

I grund och botten vill jag kalla toggleCategoriesSelection vid klick ELLER fokus - just nu kallas den 2 gånger vid första klicket. Jag hoppades att något som detta skulle fungera:

(click | focus)="toggleCategoriesSelection($event)"

Men tyvärr fungerar det inte så här. Hur kan jag göra detta?

Svar #1

Lägg till metod för att stoppa propagation till din klick- och fokus-händelse.

 <input
           #commentCategories
           class="form-add-new__category-box"
           (click)="$event.stopPropagation();$event.preventDefault();toggleCategoriesSelection($event)"
           (focus)="$event.stopPropagation();$event.preventDefault();toggleCategoriesSelection($event)"
           (keyup)="searchCategory($event.target.value)"
           tabindex="0"
           placeholder="Search or select">
     <span class="icon-arrow-down"></span>

hoppas jag hjälper dig!

Svar #2

Faktiskt kan det hända att du inte behöver kalla toggleCategoriesSelection på både click och focus händelserna. Men om du vill göra det kan du använda något som nedan.

Här tömmer vi frekventa funktionsanrop som inträffar under smallTimeout.

timeOutExceeded = true // initial value

public toggleCategoriesSelection(event: Event): void {
    if (this.timeOutExceeded) {
        // your logic
        this.timeOutExceeded = false;
        setTimeout(() => {
            this.timeOutExceeded = true;    
        }, smallTimeout);
    }
}

Du kan också titta på RXJS debouncing (eller någon annan sådan teknik) nedan.

https://medium.com/aviabird/rxjs-reducing-number-of-api-calls-to-your-server-using-debouncetime-d71c209a4613