2014-10-19 14 views
89

Ho un input che filtra una lista di ripetizioni ng al cambiamento. La ripetizione contiene molti dati e richiede alcuni secondi per filtrare tutto. Vorrei che il loro fosse un ritardo di 0,5 secondi prima di iniziare il processo di filtraggio. Qual è il modo corretto in angolare per creare questo ritardo?Ritardo cambiamento ng.

ingresso

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

Ripetere

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

Filtro Funzione

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

Grazie

+1

Basta usare un '$ timeout' per 500ms. '$ scope.FilterByName = function() {$ timeout (_filterByName, 500)' – PSL

+0

@PSL dove nella funzione? Voglio solo eseguire la ricerca una volta. Se lo compenso, creerà un ritardo maggiore e effettuerò più ricerche. – MGot90

+0

Sì, nella tua funzione. il commento precedente ha uno snippet. Puoi usare '$ timeout.cancel (timeoutpromise)' se un timeout è in corso e viene attivato un altro cambiamento. – PSL

risposta

213

An gularJS 1.3+

Dal AngularJS 1.3 si può utilizzare la proprietà debouncengModelOptions prevede il raggiungimento di tale molto facile senza usare $timeout a tutti. Ecco un esempio:

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); 
     }; 
    } 
]); 

- oppure -

Check the Fiddle

Prima AngularJS 1.3

Dovrete usare $ timeout per aggiungere un ritardo e, probabilmente, con l'uso di $ timeout.cancel (previoustimeout) si può annullare qualsiasi timeout precedente ed eseguire il nuovo (aiuta a prevenire il filtraggio da eseguire multipla volte consecutovely all'interno di un intervallo di tempo)

Ecco un esempio:

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); 
    } 
}); 
+2

Questo è molto utile. Non avevo idea che Angular avesse una funzione di rimbalzo. –

+2

Si noti che 'ng-model-options' è stato aggiunto solo in [Angular v1.3] (https://github.com/angular/angular.js/blob/master/CHANGELOG.md#v130-beta6-expedient-caffeination -2014-04-21) (e la proprietà debounce in [beta.8] (https://github.com/angular/angular.js/blob/master/CHANGELOG.md#130-beta8-accidental-haiku-2014 -05-09)). Coloro che hanno ancora bisogno di utilizzare una versione precedente di Angular dovranno ricorrere ad altre soluzioni, come quella di PSL, o usando un modulo esterno come [ng-debounce] (https://github.com/shahata/angular- antirimbalzo). –

+4

1860 caratteri cancellati dal mio controller, grazie! – paulj

17

Si potrebbe utilizzare $timeout per aggiungere un ritardo e, probabilmente, con l'uso di $timeout.cancel(previoustimeout) si può annullare qualsiasi timeout precedente ed eseguire il nuovo (aiuta a prevenire il filtraggio deve essere eseguito più volte consecutovely all'interno di un intervallo di tempo)

Esempio: -

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

+7

Per il down-voter e per i futuri visitatori: questa risposta è stata aggiunta per ** Angular 1.2.x **, e aggiunta probabilmente prima che 1.3.x sia stata rilasciata che ha il l'opzione debounce con le opzioni di ng-model e non ha mai avuto la possibilità di rivedere la risposta prima che arrivasse una risposta migliore da @rckd (circa 3 mesi dopo questa). – PSL

+3

Anche se sto usando angular js 1.4, trovo ancora la soluzione di timeout $ utile con 'ng-change' quando non voglio rimbalzare il modello. – SStanley

6

so che la questione è troppo vecchio. Ma voglio ancora fornire un modo più rapido per raggiungere questo obiettivo utilizzando debouncing.

modo che il codice può essere scritta come

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

Debounce prenderà il numero in millisecondi.

0

oppure è possibile utilizzare la direttiva 'typeahead-wait-ms = "1000"' dal 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">