Ng-change delay, angularjs

I am developing an application with angularjs that shows some text fields on a screen with numeric data. They look like this:

<input type="text" ng-model="value" ng-change="controller.functions.valueChanged(value)"> 

The problem is that every time I write a number or I delete the number from the text field, and the ng-change directives to the function. Is it possible to apply some delay king to the ng-change function?

+5
source share
4 answers

Update

you can use $ timeout to create a delay function. this can be applied to another callback

 angular.module('myApp', []); angular.module('myApp') .controller('myCtrl', ["$scope", "$log", "$timeout", function($scope, $log, $timeout) { $scope.delay = (function() { var promise = null; return function(callback, ms) { $timeout.cancel(promise); //clearTimeout(timer); promise = $timeout(callback, ms); //timer = setTimeout(callback, ms); }; })(); $scope.doSomeThing = function(value) { var current = new Date(); $scope.result = 'value:' + $scope.foo + ', last updated:' + current; }; } ]); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script> <div ng-app="myApp" ng-controller="myCtrl"> <h3>$timeout delay demo</h3> <div> <input ng-model="foo" ng-change="delay(doSomeThing, 1000)" type="text" /> </div> <div>Result: {{result}}</div> </div> 
+7
source

You can use ngModelOptions

debounce: an integer value that contains the debounce model update value in milliseconds. A value of 0 causes an immediate update.

the code

  <input type="text" ng-model-options="{ debounce: 1000 }" ng-model="value" ng-change="controller.functions.valueChanged(value)"> 
+16
source

The easiest way to do this is to set a timeout inside the controller.functions.valueChanged function.

Angularjs has the ngModelOptions directive, which is very useful for this kind of thing. You can try to install

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

for a timeout before changing the model. You can also use

 ng-model-options="{ updateOn: 'blur' }" 

Refresh the model only when the focus leaves the element.

+2
source

I use AngularJs 1.2.x and stumble upon the issue of changing ng on dismissal with every change. ng-blur can be used, but it works even if there is no change in value. Therefore, both cannot be used effectively.

With Angularjs 1.3.x, everything is simpler using ng-model-options as shown below

to call the change function "onBlur"

ng-change="ctrl.onchange()" ng-model-options="{updateOn: 'blur'}"

AND

to defer the change function call for 500 ms

ng-change="ctrl.onchange()" ng-model-options='{ debounce: 500 }'"

Now, to get back to the question of getting such things with AngularJs 1.2.x

to call the change function "onBlur"

HTML

<input type="text" ng-model="ctrl.ac" sd-change-on-blur="ctrl.onchange()" /> or

<input type="text" ng-model="ctrl.ac" sd-change-on-blur="ctrl.onchange(ctrl.ac)" />

Js

 app.directive('sdChangeOnBlur', function() { return { restrict: 'A', scope: { sdChangeOnBlur: '&' }, link: function(scope, elm, attrs) { if (attrs.type === 'radio' || attrs.type === 'checkbox') return; var parameters = getParameters(attrs.sdChangeOnBlur); var oldValue = null; elm.bind('focus', function() { scope.$apply(function() { oldValue = elm.val(); }); }) elm.bind('blur', function() { scope.$apply(function() { if (elm.val() != oldValue) { var params = {}; if (parameters && parameters.length > 0) { for (var n = 0; n < parameters.length; n++) { params[parameters[n]] = scope.$parent.$eval(parameters[n]); } } else { params = null; } if (params == null) { scope.sdChangeOnBlur(); } else { scope.sdChangeOnBlur(params) } } }); }); } }; }); function getParameters(functionStr) { var paramStr = functionStr.slice(functionStr.indexOf('(') + 1, functionStr.indexOf(')')); var params; if (paramStr) { params = paramStr.split(","); } var paramsT = []; for (var n = 0; params && n < params.length; n++) { paramsT.push(params[n].trim()); } return paramsT; } 

to defer the change function call for 500 ms

HTML

<input type="text" ng-model="name" sd-change="onChange(name)" sd-change-delay="300"/>

OR

<input type="text" ng-model="name" sd-change="onChange()" sd-change-delay="300"/>

Js

 app.directive('sdChange', ['$timeout', function($timeout) { return { restrict: 'A', scope: { sdChange: '&', sdChangeDelay: '@' //optional }, link: function(scope, elm, attr) { if (attr.type === 'radio' || attr.type === 'checkbox') { return; } if (!scope.sdChangeDelay) { scope.sdChangeDelay = 500; //defauld delay } var parameters = getParameters(attr.sdChange); var delayTimer; elm.bind('keydown keypress', function() { if (delayTimer !== null) { $timeout.cancel(delayTimer); } delayTimer = $timeout(function() { var params = {}; if (parameters && parameters.length > 0) { for (var n = 0; n < parameters.length; n++) { params[parameters[n]] = scope.$parent.$eval(parameters[n]); } } else { params = null; } if (params == null) { scope.sdChange(); } else { scope.sdChange(params) } delayTimer = null; }, scope.sdChangeDelay); scope.$on( "$destroy", function(event) { $timeout.cancel(delayTimer); console.log("Destroyed"); } ); }); } }; } ]); function getParameters(functionStr) { var paramStr = functionStr.slice(functionStr.indexOf('(') + 1, functionStr.indexOf(')')); var params; if (paramStr) { params = paramStr.split(","); } var paramsT = []; for (var n = 0; params && n < params.length; n++) { paramsT.push(params[n].trim()); } return paramsT; } 

plnkrs for both approaches

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

http://plnkr.co/edit/9PGbYGCDCtB52G8bJkjx?p=info

+2
source

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


All Articles