【问题标题】:AngularJS - Fire $timeout event on ng-change only onceAngularJS - 仅在 ng-change 上触发 $timeout 事件一次
【发布时间】:2014-12-04 20:31:03
【问题描述】:

我对绑定到范围变量的 html 中的输入字段进行了 ng-change。

<input type="text" ng-model="test" ng-change="change()" required>

var change = function(){ redraw_graph()}

现在,当我更改输入框时,它会为我写的每个新字符重新绘制图形。我想要延迟(N 秒),所以在 ng-change 事件触发之前,angular 会在用户完成输入之前等待。如果触发了多个 ng-change 事件,它会取消较早的事件并仅执行最新的事件。

我已将延迟与超时合并,但 N 秒后 ng-change 事件仍会触发多次。我以前解决过这个问题,但我现在不知道该怎么做。

【问题讨论】:

  • 在调用新的$timeout之前取消现有的@。

标签: javascript angularjs timeout


【解决方案1】:

在我看来,您所要求的似乎已经内置在 AngularJS 中。因此,如果您使用ngModelOptions 指令,您可以使用debounce 属性:

ng-model-options="{ debounce: 1000 }"

引用文档

.."/或去抖动延迟,以便仅发生实际更新 当计时器到期时;此计时器将在另一次更改后重置 发生。”


工作样本

  angular.module('optionsExample', [])
    .controller('ExampleController', ['$scope',
      function($scope) {
        $scope.user = {
          name: 'say'
        };
      }
  ]);
<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Example - example-ngModelOptions-directive-debounce-production</title>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.5/angular.min.js"></script>
  <script src="app.js"></script>
</head>

<body ng-app="optionsExample">
  <div ng-controller="ExampleController">
    <form name="userForm">
      Name:
      <input type="text" 
             name="userName" 
             ng-model="user.name" 
             ng-model-options="{ debounce: 1000 }" />
      <button ng-click="userForm.userName.$rollbackViewValue(); user.name=''">Clear</button>
      <br />
    </form>
    <pre>user.name = <span ng-bind="user.name"></span></pre>
  </div>
</body>

</html>

【讨论】:

    【解决方案2】:

    根据@Blackhole 的建议,您可以通过取消原来的 $timeout 来解决这个问题。

    你会怎么做:

    var timer;
    
    $scope.change = function(){
       $timeout.cancel( timer );
    
       timer = $timeout(function() {
                 redraw_graph()
               },2000);
     }
    

    检查下面的 plunker 以了解它是如何工作的。完成对输入字段的所有更改后 2 秒,将弹出一个警告框(仅一个)。也就是说,如果您在 2 秒之前更改输入字段,则会将弹出窗口再延迟 2 秒。

    http://plnkr.co/edit/v08RYwCDVtymNrgs48QZ?p=preview

    编辑
    虽然上面是实现它的一种方法,但 AngularJS 在 v1.3+ 中针对此特定功能提出了自己的实现。可以使用ngModelOptions

    【讨论】:

    • 使用这种方法,如果我正确阅读代码,您总是可以获得最新的值。当您只想要最新值时,这非常酷,它可以将其与ng-model-options 的去抖值进行比较,如果这适用于您的用例,这是一个有效的选项。虽然,我记得,ng-model-options 也有一个延迟选项为您执行此操作!
    【解决方案3】:

    你可以看看 UnderscoreJS,它有 .debounce().throttle()

    【讨论】:

    • debounce 已经包含在 Angular 的 ng-model-options 中,不需要下划线(尽管它是一个很酷的库)
    • 完全同意 Rohan 的观点,下划线做了很多很酷的事情,但是对于 angularJs 的这个用例来说完全不需要 ng-model-options 来为你处理这些事情,而不是让你的控制器/服务更加臃肿!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-09
    • 1970-01-01
    相关资源
    最近更新 更多