Angularjs: $watch With Debounce
I have the following html which represents a search field: And the following js: $scope.$watch('name
Solution 1:
You should be using ng-change for this sort of thing instead of wiring up a watch.
<input ng-model-options="{ debounce: 500 }"type="text" ng-model="name" ng-change="modelChanged()">
JS:
var timeout = $timeout(function(){});
$scope.modelChanged = function(){
$timeout.cancel(timeout); //cancel the last timeout
timeout = $timeout(function(){
$scope.pageChanged($scope.sort, $scope.name, $scope.sortDirection);
}, 500);
};
I'm unfamiliar with debounce, but it might achieve the same thing.
Solution 2:
Very interesting Use Case!
Answer :
I solved a similar issue by implementing the debounce
function in a service taking inspiration from lodash' implementation (also can find an implementation here (@Pete BD's answer).
// Create an AngularJS service called debounce
app.factory('debounce', ['$timeout','$q', function($timeout, $q) {
// The service is actually this function, which we call with the func// that should be debounced and how long to wait in between callsreturnfunctiondebounce(func, wait, immediate) {
var timeout;
// Create a deferred object that will be resolved when we need to// actually call the funcvar deferred = $q.defer();
returnfunction() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if(!immediate) {
deferred.resolve(func.apply(context, args));
deferred = $q.defer();
}
};
var callNow = immediate && !timeout;
if ( timeout ) {
$timeout.cancel(timeout);
}
timeout = $timeout(later, wait);
if (callNow) {
deferred.resolve(func.apply(context,args));
deferred = $q.defer();
}
return deferred.promise;
};
};
}]);
Then I included it in my controller/directive containing the $watch
and then doing the magic like so (using your code):
$scope.$watch('name', debounce(function(newVal, oldVal) {
if(newVal != oldVal) {
$scope.pageChanged($scope.sort, $scope.name, $scope.sortDirection);
}
}, 500));
DONE!
Case history:
I also tried to do like:
$scope.$watch('name', function(newVal, oldVal) {
debounce(function() {
if(newVal != oldVal) {
$scope.pageChanged($scope.sort, $scope.name, $scope.sortDirection);
},500)();
});
but without satisfaction because the watch was run twice in 50ms.
Post a Comment for "Angularjs: $watch With Debounce"