In AngularJS I was able to debounce a model by using ng-model options.
ng-model-options="{ debounce: 1000 }"
How can I debounce a model in Angular?
I tried to search for debounce in the docs but I couldn't find anything.
https://angular.io/search/#stq=debounce&stp=1
A solution would be to write my own debounce function, for example:
import {Component, Template, bootstrap} from 'angular2/angular2';
// Annotation section
@Component({
selector: 'my-app'
})
@Template({
url: 'app.html'
})
// Component controller
class MyAppComponent {
constructor() {
this.firstName = 'Name';
}
changed($event, el){
console.log("changes", this.name, el.value);
this.name = el.value;
}
firstNameChanged($event, first){
if (this.timeoutId) window.clearTimeout(this.timeoutID);
this.timeoutID = window.setTimeout(() => {
this.firstName = first.value;
}, 250)
}
}
bootstrap(MyAppComponent);
And my html
<input type=text [value]="firstName" #first (keyup)="firstNameChanged($event, first)">
But I'm looking for a built in function, is there one in Angular?
Best Answer
Updated for RC.5
With Angular 2 we can debounce using RxJS operator
debounceTime()
on a form control'svalueChanges
observable:Plunker
The code above also includes an example of how to throttle window resize events, as asked by @albanx in a comment below.
Although the above code is probably the Angular-way of doing it, it is not efficient. Every keystroke and every resize event, even though they are debounced and throttled, results in change detection running. In other words, debouncing and throttling do not affect how often change detection runs. (I found a GitHub comment by Tobias Bosch that confirms this.) You can see this when you run the plunker and you see how many times
ngDoCheck()
is being called when you type into the input box or resize the window. (Use the blue "x" button to run the plunker in a separate window to see the resize events.)A more efficient technique is to create RxJS Observables yourself from the events, outside of Angular's "zone". This way, change detection is not called each time an event fires. Then, in your subscribe callback methods, manually trigger change detection – i.e., you control when change detection is called:
Plunker
I use
ngAfterViewInit()
instead ofngOnInit()
to ensure thatinputElRef
is defined.detectChanges()
will run change detection on this component and its children. If you would rather run change detection from the root component (i.e., run a full change detection check) then useApplicationRef.tick()
instead. (I put a call toApplicationRef.tick()
in comments in the plunker.) Note that callingtick()
will causengDoCheck()
to be called.