简体   繁体   中英

Using $timeout to limit the amount of http request that go out in Angularjs 1.2 Search app

I'm doing a type ahead style form that has a ng-model of findSearchValue and when the user types in the input I watch this and when it updates I fire off the search function. The issue that I'm having is when a user types a word (for example Spaceship ) the function fires off 9 requests for Spaceship ; 1 for each letter in the word.

I tried using a timeout, but all this does is wait 900ms and then fires off all 9 requests. What would ensure that the request is only fired after the user has stopped typing for a given amount of time.

Here is my current code:

$scope.findSearchValue = '';

$scope.getFindResults = function(findSearchValue) {
  if ($scope.findSearchValue.length > 2) {
    $timeout(function(){
      $http.get('/search.json?term=' + $scope.findSearchValue).success(function(data) {
        $scope.findResults = data;
        $scope.showSearchResults = true;
      });
    }, 900);
  } else {
    $scope.showSearchResults = false;
  }
};

$scope.$watch('findSearchValue',  function(newValue, oldValue) {
  if (newValue !== oldValue) {
    $scope.getFindResults();
  }
});

Also, I know there are plenty of directives that handle this use case. I do not feel like installing a large directive just to do something so small. Thanks

Sounds like you want to debounce . You should drop the extra $timeout code and just do:

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

on the element.

EDIT : As mentioned below in the comments the above requires Angularjs 1.3. If you need to debounce but cannot upgrade your angularjs install then try something like this: github.com/shahata/angular-debounce

Store the old timeout promise and cancel it every time a new change comes. The key is to use $timeout.cancel(promise) . promise is returned by $timeout() . Using your code (untested):

$scope.findSearchValue = '';

var promise = null;
$scope.getFindResults = function(findSearchValue) {
  if ($scope.findSearchValue.length > 2) {
    if (promise) {
      $timeout.cancel(promise);
    }
    promise = $timeout(function(){
      $http.get('/search.json?term=' + $scope.findSearchValue).success(function(data) {
        $scope.findResults = data;
        $scope.showSearchResults = true;
      });
    }, 900);
  } else {
    $scope.showSearchResults = false;
  }
};

$scope.$watch('findSearchValue',  function(newValue, oldValue) {
  if (newValue !== oldValue) {
    $scope.getFindResults();
  }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM