【问题标题】:Angular ng-change delay角度 ng-change 延迟
【发布时间】:2014-12-14 07:34:41
【问题描述】:

我有一个输入,可以在更改时过滤 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
 });

谢谢

【问题讨论】:

  • 只需使用$timeout 500 毫秒。 $scope.FilterByName = function () { $timeout(_filterByName , 500)
  • @PSL 函数在哪里?我只希望搜索执行一次。如果我只是抵消它,它只会造成更大的延迟并进行多次搜索。
  • 是的,在你的功能中。上一条评论有一个sn-p。如果一个超时正在进行并且触发了另一个更改,您可以使用$timeout.cancel(timeoutpromise)。
  • @PSL 谢谢你的工作就像一个魅力!

标签: angularjs angularjs-directive angularjs-ng-repeat


【解决方案1】:

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

-- 或者--

Check the Fiddle

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

【讨论】:

  • 请注意,ng-model-options 仅在 Angular v1.3 中添加(以及在 beta.8 中的 debounce 属性)。那些仍然需要使用旧版本 Angular 的人将不得不求助于其他解决方案,例如 PSL 的解决方案,或者使用像 ng-debounce 这样的外部模块。
  • 一个缺点可能是这似乎也会延迟像 ng-pattern 这样的验证。
【解决方案2】:

您可以使用$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

【讨论】:

  • 致反对者和未来的访问者:此答案是为 Angular 1.2.x 添加的,并且可能在 1.3.x 发布之前添加,该版本具有 ng- 的 debounce 选项model-options 并且在@rckd 提供更好的答案之前(大约 3 个月后)没有机会修改答案。
  • 即使我使用的是 Angular js 1.4,当我不想让模型去抖动时,我仍然发现 $timeout 解决方案对 ng-change 很有用。
【解决方案3】:

我知道这个问题太老了。但仍想提供一种更快的方法来使用debouncing 实现这一目标。

所以代码可以写成

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

Debounce 将以毫秒为单位。

【讨论】:

    【解决方案4】:

    或者你可以使用来自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">
    

    【讨论】:

      猜你喜欢
      • 2014-02-02
      • 1970-01-01
      • 2015-01-12
      • 1970-01-01
      • 2016-08-17
      • 2017-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多