简体   繁体   English

AngularJS - ng-change上的Fire $ timeout事件只发生一次

[英]AngularJS - Fire $timeout event on ng-change only once

I have an ng-change on an input field in html that's bound to a scope variable. 我在html中的输入字段上有一个ng-change,它绑定到一个范围变量。

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

var change = function(){ redraw_graph()}

Now when I change the input box, it redraws the graph for every new character I write. 现在当我更改输入框时,它会为我写的每个新字符重绘图形。 I want to have a delay (N seconds), so angular will wait before the user is done typing before the ng-change event fires. 我希望有一个延迟(N秒),因此在ng-change事件触发之前,在用户完成输入之前,angular将等待。 And if there are multiple ng-change events fired, it cancels the earlier ones and only executes the latest ones. 如果触发了多个ng-change事件,它将取消之前的事件并仅执行最新事件。

I've incorporated the delay with a timeout, but after N seconds the ng-change event still fires more than once. 我已将延迟纳入超时,​​但在N秒后,ng-change事件仍然会多次触发。 I've solved this problem before, but I can't figure out how to do it currently. 我之前已经解决了这个问题,但我现在无法弄清楚如何做到这一点。

To me it seems like what you're asking for is already built into AngularJS. 对我来说,似乎你要求的内容已经内置于AngularJS中。 Thus, if you make use of the the ngModelOptions directive you can use the debounce property: 因此,如果你利用的的ngModelOptions指令,你可以使用debounce性能:

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

To quote the docs 引用文档

.."/or a debouncing delay so that the actual update only takes place when a timer expires; this timer will be reset after another change takes place." 。“/或去抖动延迟,以便实际更新仅在计时器到期时发生;此计时器将在另一次更改发生后重置。”


Working sample 工作样本

  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> 

Based on @Blackhole's suggestion, you can work this out by cancelling your original $timeout. 根据@ Blackhole的建议,你可以通过取消原来的$ timeout来解决这个问题。

Here is how you would do it: 以下是您将如何做到这一点:

var timer;

$scope.change = function(){
   $timeout.cancel( timer );

   timer = $timeout(function() {
             redraw_graph()
           },2000);
 }

Check below plunker to see how it works. 检查下面的plunker,看看它是如何工作的。 An alert box (only one) will popup 2 seconds after you are done with all your changes on the input field. 完成输入字段上的所有更改后,将在2秒后弹出警告框(仅一个)。 That is, if you change the input field before 2 seconds, you delay the popup by another 2 seconds. 也就是说,如果您在2秒之前更改输入字段,则会将弹出窗口再延迟2秒。

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

EDIT 编辑
While above is one method of doing it, AngularJS has come up with its own implementation for this particular feature in v1.3+. 虽然上面是一种方法,但AngularJS已经为v1.3 +中的这个特定功能提出了自己的实现。 ngModelOptions can be used. 可以使用ngModelOptions

你可能会看看.debounce() ,它有.debounce().throttle()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM