Angular ng-change delay

I have an input that filters the ng-repeat list when changed. A repeat contains a lot of data and takes a few seconds to filter everything. I would like them to be 0.5 seconds before I start the filtering process. What is the correct way in angular to create this delay?

Enter

<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 }); 

thank

+84
angularjs angularjs-ng-repeat angularjs-directive
Oct 19 '14 at 2:29 on
source share
4 answers

AngularJS 1.3 +

Since AngularJS 1.3 you can use the debounce property of ngModelOptions , you can achieve this very easily without using $timeout at all. Here is 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 -

Check script

Before AngularJS 1.3

You need to use $ timeout to add a delay, and perhaps using $ timeout.cancel (previoustimeout), you can undo any previous timeout and start a new one (helps prevent multiple filtering from happening repeatedly over a period of time)

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); } }); 
+196
Jan 15 '15 at 8:43
source share

You can use $timeout to add a delay and, possibly using $timeout.cancel(previoustimeout) , you can undo any previous timeout and start a new one (helps to prevent filtering from being performed several times in a row during the 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); } }); 

Plnkr

+17
Oct 19 '14 at 2:54 on
source share

I know the question is too old. But still want to provide one faster way to achieve this using debouncing .

Thus, the code can be written as

 <input ng-model="xyz" ng-change="FilterByName()" ng-model-options="{debounce: 500}"/> 

The debit will take a number in milliseconds.

+5
Aug 17 '16 at 15:51
source share

or you can use the 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"> 
0
Nov 01 '16 at 15:11
source share



All Articles