Angular ng-change delay


117

変更時にng-repeatリストをフィルタリングする入力があります。リピートには多くのデータが含まれており、すべてをフィルタリングするには数秒かかります。フィルタリングプロセスを開始する前に、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
$timeout500ms だけ使用します。$scope.FilterByName = function () { $timeout(_filterByName , 500)
PSL 2014年

@PSL関数のどこに?検索を1回だけ実行したい。オフセットしただけでは、遅延が大きくなり、複数の検索が実行されます。
MGot90 2014年

ええ、あなたの機能で。前のコメントにはスニペットがあります。$timeout.cancel(timeoutpromise)1つのタイムアウトが進行中で別の変更がトリガーされた場合に使用できます。
PSL 2014年


1
@PSLありがとうございます。
MGot90 2014年

回答:


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(およびbeta.8の debounceプロパティ)でのみ追加されたことに注意してください。それでも古いバージョンのAngularを使用する必要がある場合は、PSLのソリューションやng-debounceなどの外部モジュールを使用するなど、他のソリューションを使用する必要があります。
Vincent Sels、2015

欠点は、これがng-patternのような検証も遅延させるように見えることです。
Johan Baaij 16

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

Plnkr


8
反対投票者と将来の訪問者へ:この回答はAngular 1.2.xに追加され、おそらく1.3.xがリリースされる前に追加されました。これにはng-model-optionsのデバウンスオプションがあり、より良い前に回答を修正する機会がありませんでした。 @rckdからの回答が届きました(この回答から約3か月後)。
PSL

4
Angular js 1.4を使用していますがng-change、モデルをデバウンスしたくない場合でも$ timeoutソリューションが便利です。
SStanley 2016年

8

質問が古すぎることは知っています。しかし、デバウンスを使用してこれを実現するための1つのより迅速な方法を提供したいと考えています。

したがって、コードは次のように書くことができます

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

デバウンスにはミリ秒単位の数値がかかります。


0

または、angular-uiのディレクティブ 'typeahead-wait-ms = "1000"'を使用できます

<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">
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.