web-dev-qa-db-fra.com

Angular retard de changement

J'ai une entrée qui filtre une liste ng-repeat sur le changement. La répétition contient beaucoup de données et prend quelques secondes pour tout filtrer. Je voudrais qu'il y ait un délai de 0,5 seconde avant que je commence le processus de filtrage. Quelle est la bonne manière dans angular de créer ce délai?

Entrée

 <input ng-model="xyz" ng-change="FilterByName()" />

Répéter

 <div ng-repeat"foo in bar">
      <p>{{foo.bar}}</p>
 </div>

fonction de filtrage

 $scope.FilterByName = function () {
      //Filtering Stuff Here
 });

Merci

114
MGot90

AngularJS 1.3 +

Depuis AngularJS 1.3, vous pouvez utiliser la propriété debouncengModelOptions permet de réaliser cela très facilement sans utiliser $timeout. Voici un exemple:

HTML:

<div ng-app='app' ng-controller='Ctrl'>
    <input type='text' placeholder='Type a name..'
        ng-model='vm.name'
        ng-model-options='{ debounce: 1000 }'
        ng-change='vm.greet()'
    />

    <p ng-bind='vm.greeting'></p>
</div>

JS:

angular.module('app', [])
.controller('Ctrl', [
    '$scope',
    '$log',
    function($scope, $log){
        var vm = $scope.vm = {};

        vm.name = '';
        vm.greeting = '';
        vm.greet = function greet(){
            vm.greeting = vm.name ? 'Hey, ' + vm.name + '!' : '';
            $log.info(vm.greeting);
        };
    }
]);

- OR -

Vérifiez le violon

Avant AngularJS 1.3

Vous devrez utiliser $ timeout pour ajouter un délai et probablement avec l'utilisation de $ timeout.cancel (previous timeout), vous pouvez annuler tout délai précédent et exécuter le nouveau (aide à empêcher le filtrage d'être exécuté plusieurs fois de suite dans un délai plus court). intervalle de temps)

Voici un exemple:

app.controller('MainCtrl', function($scope, $timeout) {
    var _timeout;

    //...
    //...

    $scope.FilterByName = function() {
        if(_timeout) { // if there is already a timeout in process cancel it
            $timeout.cancel(_timeout);
        }
        _timeout = $timeout(function() {
            console.log('filtering');
            _timeout = null;
        }, 500);
    }
});
267
rckd

Vous pouvez utiliser $timeout pour ajouter un délai et probablement avec l'utilisation de $timeout.cancel(previoustimeout), vous pouvez annuler tout délai d'attente précédent et exécuter le nouveau (aide à empêcher le filtrage d'être exécuté plusieurs fois consécutives dans un intervalle de temps)

Exemple:-

_app.controller('MainCtrl', function($scope, $timeout) {
  var _timeout;

 //...
 //...

  $scope.FilterByName = function () {
    if(_timeout){ //if there is already a timeout in process cancel it
      $timeout.cancel(_timeout);
    }
    _timeout = $timeout(function(){
      console.log('filtering');
      _timeout = null;
    },500);
  }
 });
_

Plnkr

19
PSL

Je sais que la question est trop ancienne. Mais vous voulez toujours fournir un moyen plus rapide pour y parvenir en utilisant debouncing .

Donc, le code peut être écrit comme

<input ng-model="xyz" ng-change="FilterByName()" ng-model-options="{debounce: 500}"/>

Debounce prendra le nombre en millisecondes.

7
Naibedya Kar

ou vous pouvez utiliser la directive 'typeahead-wait-ms = "1000"' de angular-ui

<input 
   typeahead="name for name in filterWasChanged()"
   typeahead-wait-ms="1000"
   type="text" placeholder="search"
   class="form-control" style="text-align: right" 
   ng-model="templates.model.filters.name">
0
Vadym Kaptan