<button
type="button"
appDebounceClick
[debounceTime]="800"
(appDebounceClick)="submitOrder()"
>
Place Order
</button>- Prevent double form submission
- Avoid duplicate API calls
- Order placement / trading actions
- Any critical UI interaction
| import { | |
| Directive, | |
| DestroyRef, | |
| EventEmitter, | |
| HostListener, | |
| Input, | |
| OnInit, | |
| Output, | |
| inject, | |
| } from '@angular/core'; | |
| import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; | |
| import { Subject, throttleTime } from 'rxjs'; | |
| @Directive({ | |
| selector: '[appDebounceClick]', | |
| standalone: true, | |
| }) | |
| export class DebounceClickDirective implements OnInit { | |
| @Input() debounceTime = 500; | |
| @Output() appDebounceClick = new EventEmitter<MouseEvent>(); | |
| private readonly clicks$ = new Subject<MouseEvent>(); | |
| private readonly destroyRef = inject(DestroyRef); | |
| ngOnInit(): void { | |
| this.clicks$ | |
| .pipe( | |
| throttleTime(this.debounceTime), | |
| takeUntilDestroyed(this.destroyRef) | |
| ) | |
| .subscribe((event) => this.appDebounceClick.emit(event)); | |
| } | |
| @HostListener('click', ['$event']) | |
| handleClick(event: MouseEvent): void { | |
| this.clicks$.next(event); | |
| } | |
| } |