Кутова затримка зміни нг


117

У мене є вхід, який фільтрує список ng-повторів при зміні. Повторення містить велику кількість даних і займає кілька секунд, щоб усе профільтрувати. Я хотів би, щоб їх було 0,5 секунди, перш ніж розпочати процес фільтрації. Який правильний спосіб утворити цю затримку?

Вхідні дані

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

Повторіть

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

Функція фільтра

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

Дякую


1
Просто використовуйте $timeout500 мс. $scope.FilterByName = function () { $timeout(_filterByName , 500)
ПСЛ

@PSL де у функції? Я хочу лише здійснити пошук. Якщо я просто компенсую це, це просто створить більшу затримку і зробить кілька запитів.
MGot90

Так, у вашій функції. prev коментар має фрагмент. Ви можете використовувати, $timeout.cancel(timeoutpromise)якщо проходить один тайм-аут, і інша зміна починається.
ПСЛ


1
@PSL Дякую, працює як шарм!
MGot90

Відповіді:


273

AngularJS 1.3+

Оскільки AngularJS 1.3 ви можете використовувати debounceвластивість, що ngModelOptionsдозволяє досягти цього дуже просто, не використовуючи $timeoutзовсім. Ось приклад:

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

- АБО -

Перевірте Скрипку

До AngularJS 1.3

Вам потрібно буде використовувати $ timeout, щоб додати затримку, і, ймовірно, за допомогою $ timeout.cancel (previoustimeout) ви можете скасувати будь-який попередній тайм-аут і запустити новий (допомагає запобігти виконанню фільтрації кілька разів послідовно протягом проміжок часу)

Ось приклад:

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
Зауважте, що ng-model-optionsдодано лише у Angular v1.3 (а властивість debounce у бета-версії 8 ). Тим, хто все ще потребує використання старішої версії Angular, доведеться вдатися до інших рішень, наприклад, від PSL або до використання зовнішнього модуля, наприклад ng-debounce .
Vincent Sels

Мінусом може бути те, що це, здається, затримує перевірки, як і ng-pattern.
Йохан Баайй

19

Ви можете використовувати $timeoutдля додавання затримки, і, ймовірно, з використанням $timeout.cancel(previoustimeout)ви можете скасувати будь-який попередній час та запустити новий (допомагає запобігти виконанню фільтрації кілька разів послідовно протягом інтервалу часу)

Приклад: -

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

Плнкр


8
Для прихильників та майбутніх відвідувачів: Ця відповідь була додана для Angular 1.2.x та додана, ймовірно, до виходу 1.3.x, який має опцію дебютації з ng-model-options та ніколи не отримав шансу переглянути відповідь перед кращим відповідь від @rckd надійшла (приблизно через 3 місяці після цього).
ПСЛ

4
Незважаючи на те, що я використовую кутовий js 1.4, я все-таки вважаю корисним рішення для $ timeout, ng-changeколи я не хочу знімати модель.
SStanley

8

Я знаю, що питання занадто старе. Але все-таки хочуть надати один швидший спосіб досягти цього за допомогою деблокування .

Отже код можна записати як

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

Дебюнс прийме число в мілісекундах.


0

або ви можете використовувати директиву 'typeahead-wait-ms = "1000"' з 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">
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.