Độ trễ ng-thay đổi góc


117

Tôi có một đầu vào lọc danh sách ng-lặp lại khi thay đổi. Việc lặp lại chứa rất nhiều dữ liệu và mất vài giây để lọc qua mọi thứ. Tôi muốn chúng trễ 0,5 giây trước khi tôi bắt đầu quá trình lọc. Cách đúng trong góc để tạo ra độ trễ này là gì?

Đầu vào

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

Nói lại

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

Chức năng lọc

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

Cảm ơn


1
Chỉ cần sử dụng a $timeouttrong 500ms. $scope.FilterByName = function () { $timeout(_filterByName , 500)
PSL

@PSL ở đâu trong hàm? Tôi chỉ muốn tìm kiếm thực hiện một lần. Nếu tôi chỉ bù đắp nó, nó sẽ chỉ tạo ra độ trễ lớn hơn và thực hiện nhiều tìm kiếm.
MGot90

Vâng, trong chức năng của bạn. bình luận trước có một đoạn trích. Bạn có thể sử dụng $timeout.cancel(timeoutpromise)nếu một thời gian chờ đang diễn ra và một thay đổi khác được kích hoạt.
PSL


1
@PSL Cảm ơn bạn làm việc như một cái duyên!
MGot90

Câu trả lời:


273

AngularJS 1.3+

Kể từ AngularJS 1.3, bạn có thể sử dụng thuộc debouncetính được ngModelOptionscung cấp để đạt được điều đó rất dễ dàng mà không cần sử dụng$timeout chút nào. Đây là một ví dụ:

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

-- HOẶC LÀ --

Kiểm tra Fiddle

Trước AngularJS 1.3

Bạn sẽ phải sử dụng $ timeout để thêm thời gian trễ và có thể với việc sử dụng $ timeout.cancel (trước đó hết thời gian), bạn có thể hủy bất kỳ thời gian chờ nào trước đó và chạy thời gian chờ mới (giúp ngăn việc lọc được thực hiện nhiều lần một cách nhất quán trong một Khoảng thời gian)

Đây là một ví dụ:

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
Lưu ý rằng điều đó ng-model-optionschỉ được thêm vào Angular v1.3 (và thuộc tính debounce trong phiên bản beta.8 ). Những người vẫn cần sử dụng phiên bản Angular cũ hơn sẽ phải sử dụng các giải pháp khác, như giải pháp từ PSL hoặc bằng cách sử dụng mô-đun bên ngoài như ng-debounce .
Vincent Sels

Một nhược điểm có thể là điều này dường như cũng làm chậm trễ các xác thực như ng-pattern.
Johan Baaij

19

Bạn có thể sử dụng $timeoutđể thêm thời gian trễ và có thể với việc sử dụng $timeout.cancel(previoustimeout)bạn có thể hủy bỏ bất kỳ thời gian chờ nào trước đó và chạy thời gian chờ mới (giúp ngăn bộ lọc được thực hiện nhiều lần một cách nhất quán trong một khoảng thời gian)

Thí dụ:-

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
Đối với những người phản đối và khách truy cập trong tương lai: Câu trả lời này đã được thêm vào Angular 1.2.x và có thể được thêm vào trước khi 1.3.x được phát hành, có tùy chọn gỡ lỗi với ng-model-options và không bao giờ có cơ hội sửa đổi câu trả lời trước khi tốt hơn câu trả lời từ @rckd đến (khoảng 3 tháng sau câu trả lời này).
PSL

4
Mặc dù tôi đang sử dụng góc js 1.4, tôi vẫn thấy giải pháp $ timeout hữu ích ng-changekhi tôi không muốn làm hỏng mô hình.
SStanley

8

Tôi biết câu hỏi đã quá cũ. Nhưng vẫn muốn cung cấp một cách nhanh hơn để đạt được điều này bằng cách sử dụng gỡ lỗi .

Vì vậy, mã có thể được viết là

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

Debounce sẽ lấy số lượng tính bằng mili giây.


0

hoặc bạn có thể sử dụng chỉ thị 'typeahead-wait-ms = "1000"' từ angle-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">
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.