Very often users send request to server on change events. It would be nice to have changeDebounceTime @Input() property for numeric-textbox/dropdownlist/combobox ... change event so we can avoid all this code:
#myNumericTextBox@ViewChild('myNumericTextBox') myNumericTextBox: ElementRef;this.myNumericTextBox.valueChange.debounceTime(200).subscribe(...Adding an option for debouncing events is a bit too narrow for general use. The debounceTime operator might not be sufficient or adequate for some use cases. In addition, any timer-related operators trigger an application-wide CD.
My suggestion is to implement a directive that attaches to valueChange and exposes a debounced event.
I've created a sample afterValueChanged directive that can be applied in such cases, see sample on StackBlitz. If you find it useful, we can include it in the documentation.
import {
Directive,
Input,
HostListener,
OnDestroy,
Output,
EventEmitter
} from '@angular/core';
import { Subject, Subscription, pipe } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
@Directive({
selector: '[afterValueChanged]'
})
export class AfterValueChangedDirective implements OnDestroy {
@Output()
public afterValueChanged: EventEmitter<any> = new EventEmitter<any>();
@Input()
public valueChangeDelay: number = 300;
private stream: Subject<any> = new Subject<any>();
private subscription: Subscription;
constructor() {
this.subscription = this.stream
.pipe(debounceTime(this.valueChangeDelay))
.subscribe((value: any) => this.afterValueChanged.next(value));
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
@HostListener('valueChange', [ '$event' ])
public onValueChange(value: any): void {
this.stream.next(value);
}
}
/cc @ggkrustev
@tsvetomir
This is so awesome, you should include it in source not the documentation.
Although this solution will not work for grid filtering or on kendo-components which doesn't have valueChange event, but very similay code can be used for that. Am I right? The only thing that must be changed is selector and @HostListener?
In this case this is perfect for me.
And I must say, I am really happy to see kendo using StackBlitz. 馃憤 馃憦
I feel the snippet has more value as an example, as it is not too complex and can be applied in many scenarios - say for debouncing the change event of an input. There's also a tiny chance of Angular introducing a built-in feature that will potentially obsolete it.
Debouncing the grid filters can't be done externally unless you implement a custom filter. Therefore we included a built-in debounce in the latest development build. The delay can be adjusted through StringFilterCellComponent.filterDelay and NumericFilterCellComponent.filterDelay.
We're big fans of StackBlitz and we're working on moving all our documentation examples there.
The sample directive was published on the Debouncing Value Changes help article.
A similar approach works for debouncing the server calls when changing the filter value of an Autocomplete control. The only difference is the listened event:
@HostListener("filterChange", [ "$event" ])
public onFilterValueChange(value: any): void {
this.stream.next(value);
}
Most helpful comment
I've created a sample
afterValueChangeddirective that can be applied in such cases, see sample on StackBlitz. If you find it useful, we can include it in the documentation./cc @ggkrustev