Penundaan ng-perubahan sudut


117

Saya memiliki masukan yang memfilter daftar ng-pengulangan pada perubahan. Pengulangan berisi banyak data dan membutuhkan beberapa detik untuk menyaring semuanya. Saya ingin penundaan mereka menjadi 0,5 detik sebelum saya memulai proses penyaringan. Bagaimana cara sudut yang benar untuk membuat penundaan ini?

Memasukkan

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

Ulang

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

Fungsi Filter

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

Terima kasih


1
Cukup gunakan $timeoutuntuk 500ms. $scope.FilterByName = function () { $timeout(_filterByName , 500)
PSL

@PSL di mana fungsinya? Saya hanya ingin pencarian dilakukan satu kali. Jika saya mengimbanginya, itu hanya akan membuat penundaan yang lebih besar dan melakukan banyak pencarian.
MGot90

Ya, dalam fungsi Anda. komentar sebelumnya memiliki potongan. Anda dapat menggunakan $timeout.cancel(timeoutpromise)jika satu waktu tunggu sedang berlangsung dan perubahan lain dipicu.
PSL


1
@PSL Terima kasih bekerja seperti pesona!
MGot90

Jawaban:


274

AngularJS 1.3+

Sejak AngularJS 1.3 Anda dapat memanfaatkan debounceproperti yang ngModelOptionsdisediakan untuk mencapai itu dengan sangat mudah tanpa menggunakan $timeoutsama sekali. Berikut contohnya:

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

-- ATAU --

Periksa Biola

Sebelum AngularJS 1.3

Anda harus menggunakan $ timeout untuk menambahkan penundaan dan mungkin dengan penggunaan $ timeout.cancel (previoustimeout) Anda dapat membatalkan batas waktu sebelumnya dan menjalankan yang baru (membantu mencegah pemfilteran dijalankan beberapa kali secara berurutan dalam jarak waktu)

Berikut ini contohnya:

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
Perhatikan ng-model-optionsitu hanya ditambahkan di Angular v1.3 (dan properti debounce di beta.8 ). Mereka yang masih perlu menggunakan Angular versi lama harus menggunakan solusi lain, seperti dari PSL, atau dengan menggunakan modul eksternal seperti ng-debounce .
Vincent Sels

Sisi negatifnya adalah ini tampaknya menunda validasi seperti pola-ng juga.
Johan Baaij

19

Anda dapat menggunakan $timeoutuntuk menambahkan penundaan dan mungkin dengan penggunaan $timeout.cancel(previoustimeout)Anda dapat membatalkan waktu tunggu sebelumnya dan menjalankan yang baru (membantu mencegah pemfilteran dijalankan beberapa kali secara berurutan dalam interval waktu)

Contoh:-

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
Untuk downvoter dan pengunjung yang akan datang: Jawaban ini telah ditambahkan untuk Angular 1.2.x , dan mungkin ditambahkan sebelum 1.3.x dirilis yang memiliki opsi debounce dengan ng-model-options dan tidak pernah mendapat kesempatan untuk merevisi jawaban sebelum yang lebih baik jawaban dari @rckd masuk (sekitar 3 bulan setelah yang ini).
PSL

4
Meskipun saya menggunakan angular js 1.4 saya masih menemukan solusi batas waktu $ berguna ng-changeketika saya tidak ingin menolak model.
SStanley

8

Saya tahu pertanyaan itu terlalu tua. Namun tetap ingin menyediakan satu cara yang lebih cepat untuk mencapai hal ini dengan menggunakan debouncing .

Jadi kodenya bisa ditulis sebagai

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

Debounce akan mengambil angka dalam milidetik.


0

atau Anda dapat menggunakan perintah 'typeahead-wait-ms = "1000"' dari 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">
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.