AngularJS - Event with fire $ timeout on ng-change only once

I have an ng change in an input field in html that is associated with a scope variable.

<input type="text" ng-model="test" ng-change="change()" required> var change = function(){ redraw_graph()} 

Now, when I change the input field, it redraws the graph for each new character that I write. I want to have a delay (N seconds), so angular will wait until the user completes the input before the ng-change event occurs. And if there are several ng change events, they will undo the earlier ones and only execute the last ones.

I enabled a timeout delay, but after N seconds, the ng-change event still fires more than once. I have solved this problem before, but I canโ€™t figure out how to do it now.

+6
source share
3 answers

It seems to me that what you are asking for is already built into AngularJS. Thus, if you use the ngModelOptions directive, you can use the debounce property:

ng-model-options="{ debounce: 1000 }"

To quote documents

.. "/ or debouncing delay, so the actual update only happens when the timer expires; this timer will be reset after another change takes place."


Working example

  angular.module('optionsExample', []) .controller('ExampleController', ['$scope', function($scope) { $scope.user = { name: 'say' }; } ]); 
 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Example - example-ngModelOptions-directive-debounce-production</title> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.5/angular.min.js"></script> <script src="app.js"></script> </head> <body ng-app="optionsExample"> <div ng-controller="ExampleController"> <form name="userForm"> Name: <input type="text" name="userName" ng-model="user.name" ng-model-options="{ debounce: 1000 }" /> <button ng-click="userForm.userName.$rollbackViewValue(); user.name=''">Clear</button> <br /> </form> <pre>user.name = <span ng-bind="user.name"></span></pre> </div> </body> </html> 
+8
source

Based on the @Blackhole suggestion, you can do this by canceling the original $ timeout.

Here's how you do it:

 var timer; $scope.change = function(){ $timeout.cancel( timer ); timer = $timeout(function() { redraw_graph() },2000); } 

Check the plunker to see how it works. After you are done with all the changes in the input field, a warning window will appear (only one). That is, if you change the input field to 2 seconds, you will close the pop-up window for another 2 seconds.

http://plnkr.co/edit/v08RYwCDVtymNrgs48QZ?p=preview

EDIT
Although the above is one way to do it, AngularJS has developed its own implementation for this feature in version 1.3. ngModelOptions .

+2
source

You can check out UnderscoreJS which has .debounce() and .throttle()

0
source

Source: https://habr.com/ru/post/976522/


All Articles