Can I debounce or throttle a watched <input> in AngularJS using _lodash?
You can use ngModelOptions in Angular 1.3.0
HTML:
<div ng-controller="Ctrl"> <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>
More Info: https://docs.angularjs.org/api/ng/directive/ngModelOptions
Is that what are you looking for?
$scope.$watch("id", _.debounce(function (id) { // Code that does something based on $scope.id // This code will be invoked after 1 second from the last time 'id' has changed.}, 1000));
Note, however, that if you want to change $scope inside that function you should wrap it $scope.$apply(...)
as unless _.debounce
function uses $timeout
internally (which as far as I understand it doesn't do) Angular will not be aware of the changes you did on the $scope
.
UPDATE
As to the updated question - yes you need to wrap the entire callback function body with
$scope.$apply()
:
$scope.$watch("id", _.debounce(function (id) { // This code will be invoked after 1 second from the last time 'id' has changed. $scope.$apply(function(){ // Code that does something based on $scope.id })}, 1000));
I know the question asks for a lodash solution. Anyway here is an angular only solution:
app.factory('debounce', function($timeout) { return function(callback, interval) { var timeout = null; return function() { $timeout.cancel(timeout); var args = arguments; timeout = $timeout(function () { callback.apply(this, args); }, interval); }; }; });
In the controller:
app.controller('BlaCtrl', function(debounce) { $scope.$watch("id", debounce(function (id) { .... }, 1000));});