Angular ng-change delay
AngularjsAngularjs DirectiveAngularjs Ng-RepeatAngularjs Problem Overview
I have an input which filters a ng-repeat list on change. The repeat contains a lot of data and takes a few seconds to filter through everything. I would like their to be 0.5 second delay before I start the filtering process. What is the correct way in angular to create this delay?
Input
<input ng-model="xyz" ng-change="FilterByName()" />
Repeat
<div ng-repeat"foo in bar">
<p>{{foo.bar}}</p>
</div>
Filter Function
$scope.FilterByName = function () {
//Filtering Stuff Here
});
Thanks
Angularjs Solutions
Solution 1 - Angularjs
AngularJS 1.3+
Since AngularJS 1.3 you can utilize the debounce
property ngModelOptions
provides to achieve that very easy without using $timeout
at all. Here's an example:
HTML:
<div ng-app='app' ng-controller='Ctrl'>
<input type='text' placeholder='Type a name..'
ng-model='vm.name'
ng-model-options='{ debounce: 1000 }'
ng-change='vm.greet()'
/>
<p ng-bind='vm.greeting'></p>
</div>
JS:
angular.module('app', [])
.controller('Ctrl', [
'$scope',
'$log',
function($scope, $log){
var vm = $scope.vm = {};
vm.name = '';
vm.greeting = '';
vm.greet = function greet(){
vm.greeting = vm.name ? 'Hey, ' + vm.name + '!' : '';
$log.info(vm.greeting);
};
}
]);
-- OR --
Before AngularJS 1.3
You'll have to use $timeout to add a delay and probably with the use of $timeout.cancel(previoustimeout) you can cancel any previous timeout and run the new one(helps to prevent the filtering to be executed multiple times consecutovely within a time interval)
Here is an example:
app.controller('MainCtrl', function($scope, $timeout) {
var _timeout;
//...
//...
$scope.FilterByName = function() {
if(_timeout) { // if there is already a timeout in process cancel it
$timeout.cancel(_timeout);
}
_timeout = $timeout(function() {
console.log('filtering');
_timeout = null;
}, 500);
}
});
Solution 2 - Angularjs
You could use $timeout
to add a delay and probably with the use of $timeout.cancel(previoustimeout)
you can cancel any previous timeout and run the new one(helps to prevent the filtering to be executed multiple times consecutovely within a time interval)
Example:-
app.controller('MainCtrl', function($scope, $timeout) {
var _timeout;
//...
//...
$scope.FilterByName = function () {
if(_timeout){ //if there is already a timeout in process cancel it
$timeout.cancel(_timeout);
}
_timeout = $timeout(function(){
console.log('filtering');
_timeout = null;
},500);
}
});
Solution 3 - Angularjs
I know the question is too old. But still want to provide one quicker way to achieve this using debouncing.
So the code can be written as
<input ng-model="xyz" ng-change="FilterByName()" ng-model-options="{debounce: 500}"/>
Debounce will take the number in milliseconds.
Solution 4 - Angularjs
or you can use directive ' typeahead-wait-ms="1000" ' from angular-ui
<input
typeahead="name for name in filterWasChanged()"
typeahead-wait-ms="1000"
type="text" placeholder="search"
class="form-control" style="text-align: right"
ng-model="templates.model.filters.name">