简体   繁体   English

ng-model-options去抖动无法按预期在模糊事件上起作用?

[英]ng-model-options debounce not working on blur event as expected?

I have applied ng-model-options on input with following configuration 我已经在input使用以下配置应用了ng-model-options

ng-model-options="{updateOn:'default blur',debounce:{default:1000,blur:0}}"

And as per the applied configuration to the ng-model-options I am expecting the updated ng-model's value on ng-blur event but it doesn't return the new value despite having set 0 debounce value for blur event. 并且根据对ng-model-options的应用配置,我期望ng-blur事件上更新的ng-model's值,但是即使为blur事件设置了0反跳值,它也不会返回新值。

*Note: This problem is occurred only if user focused out before the time given in the default debounce ie 1000 *注意:仅当用户在default防抖中指定的时间之前将注意力集中在1000时,才会出现此问题

HTML: HTML:

<input type="text" ng-model="myname" ng-blur="onBlur(myname)" ng-model-options="{updateOn:'default blur',debounce:{default:1000,blur:0}}">
<input type="text" ng-model="output"/>

JS: JS:

$scope.myname = "Yogesh";
$scope.output = "";
$scope.onBlur = function(a){
   $scope.output = a;
}

Plunker link: https://embed.plnkr.co/XJMUUD/ 柱塞链接: https ://embed.plnkr.co/XJMUUD/

Why debounce is not working? 为什么去抖动不起作用? correct me if I am doing wrong any! 如果我做错了,请纠正我!

Thanks in advance :) 提前致谢 :)

I also have given the answer to my question! 我也回答了我的问题! let me know how it is flexible to use and how it will help to reduce event digest cycles. 让我知道如何灵活使用以及如何帮助减少事件摘要周期。

How ng-model-options will help to reduce event digest cycles? ng-model-options如何帮助减少事件摘要周期?

Yes, ng-model-options can help you limit the number of $digest cycles. 是的, ng-model-options可以帮助您限制$digest循环的数量。 If you were to use just ng-model without setting any options for it, then your $digest cycle will run for each change in the value of ng-model. 如果仅使用ng-model而不设置任何选项,则$ digest循环将针对ng-model值的每次更改运行。 If $digest cycle is packed full of data to be dirty-checked, the user is going to see lag in the UI whilst (for instance) typing inside an .Here is an example referenced from toddmotto's blog. 如果$digest循环中塞满了所有数据以进行脏检查,则用户将在UI中看到滞后,例如(在其中)键入。这里是toddmotto博客中引用的示例。

 // app.js angular .module('app', []); function trackDigests($rootScope) { function link($scope, $element, $attrs) { var count = 0; function countDigests(newValue, oldValue) { count++; $element[0].innerHTML = '$digests: ' + count; } $rootScope.$watch(countDigests); } return { restrict: 'EA', link: link }; } angular .module('app') .directive('trackDigests', trackDigests); 
 <script src="//code.angularjs.org/1.4.7/angular.min.js"></script> <div ng-app="app"> <div> <form name="myForm"> <h3>Standard &lt;input&gt;</h3> <track-digests></track-digests> <input type="text" name="test" ng-model="test"> </form> </div> </div> 

As you can see from our standard input, $digest cycle is getting triggered for each character we type in the input field. 从标准输入中可以看到,我们在输入字段中键入的每个字符都会触发$digest循环。 This may cause end user delay for large applications. 对于大型应用程序,这可能会导致最终用户延迟。

Now we will see the case for inputs with ng-model options. 现在,我们将看到带有ng-model选项的输入的情况。

 // app.js angular .module('app', []); function trackDigests($rootScope) { function link($scope, $element, $attrs) { var count = 0; function countDigests(newValue, oldValue) { count++; $element[0].innerHTML = '$digests: ' + count; } $rootScope.$watch(countDigests); } return { restrict: 'EA', link: link }; } angular .module('app') .directive('trackDigests', trackDigests); 
 <script src="//code.angularjs.org/1.4.7/angular.min.js"></script> <div ng-app="app"> <div> <form name="myForm"> <h3>ngModelOptions &lt;input&gt;</h3> <track-digests></track-digests> <input type="text" name="test" ng-model="test" ng-model-options="{ updateOn: 'blur' }"> </form> </div> </div> 

Here we can see that the $digest cycle is getting triggered only when we lose focus from the input. 在这里我们可以看到,仅当我们失去输入焦点时,才会触发$digest循环。 So, basically the ngModelOptions are giving us control over how and when $digest cycles occur. 因此,基本上ngModelOptions使我们可以控制$digest循环的发生方式和时间。

Let us take even more control over the $digest cycle by introducing debounce so that we can tell angular when to update. 让我们通过引入反跳控制来更好地控制$digest循环,以便我们可以知道何时更新。

 // app.js angular .module('app', []); function trackDigests($rootScope) { function link($scope, $element, $attrs) { var count = 0; function countDigests(newValue, oldValue) { count++; $element[0].innerHTML = '$digests: ' + count; } $rootScope.$watch(countDigests); } return { restrict: 'EA', link: link }; } angular .module('app') .directive('trackDigests', trackDigests); 
 <script src="//code.angularjs.org/1.4.7/angular.min.js"></script> <div ng-app="app"> <div> <form name="myForm"> <h3>ngModelOptions &lt;input&gt;</h3> <track-digests></track-digests> <input type="text" name="test" ng-model="test" ng-model-options="{ updateOn: 'default blur', debounce: { 'default': 250, 'blur': 0 } }"> </form> </div> </div> 

The above illustrates that default will be updated 250ms after the event stops, and blur will update immediately as the user leaves the input (if this is the desired behaviour we want). 上面的示例说明了默认值将在事件停止后250毫秒内更新,并且模糊将在用户离开输入时立即更新(如果这是我们想要的行为)。

Start typing again, then stop and note the $digest count is severely lower than the initial demonstration. 再次开始输入,然后停止并注意$digest计数严重低于初始演示。 You can then click/tab out the to call another $digest immediately. 然后,您可以单击/跳出,立即调用另一个$digest


What is difference between default and change in debounce? 默认值和去抖动变化之间有什么区别?

Default and change in debounce objects property are nothing but events. 默认值和去抖动对象的更改属性不过是事件。 Default is not a DOM event, this is simply part of the ng-model-options api. 默认不是DOM事件,这只是ng-model-options api的一部分。 Suppose you are setting your ngModelOptions like 假设您将ngModelOptions设置为

 ng-model-options="{ updateOn: 'default' }" 

Then there will be no change in the behaviour of your input field from default behaviour. 这样,您的输入字段的行为就不会更改为默认行为。 This configuration is not really useful until we combine it with debounce like 除非我们将其与防抖结合使用,否则此配置实际上没有用

 ng-model-options="{ updateOn: 'default', debounce: { 'default': 500 } }" 

This will make the input to update after 500ms. 这将使输入在500ms之后更新。 So basically this answers what default is. 因此,基本上,这可以回答默认值。 You can use other DOM events like change,blur,mouseover ...etc for your debounce. 您可以将其他DOM事件(例如change,blur,mouseover等)用于反跳。


Update : 更新

When you used ng-model-options="{updateOn:'default blur',debounce:{default:1000,blur:0}}" , the ng-blur was getting triggered with the old value of ng-model and after that only the updateOn events were fired.So basically the output will contain the old value of ng-model though the myname will be updated. 当您使用ng-model-options="{updateOn:'default blur',debounce:{default:1000,blur:0}}" ,ng-blur被ng-model的旧值触发,之后虽然只有updateOn事件被触发,所以虽然myname会被更新,但基本上输出将包含ng-model的旧值。

Working Example : https://plnkr.co/edit/2JPHXvXd992JJ0s37YC9?p=preview 工作示例https : //plnkr.co/edit/2JPHXvXd992JJ0s37YC9?p=preview

Now, when you used ng-model-options="{updateOn:'default change blur',debounce:{default:1000,blur:0,change:0}}" ,the ng-blur was getting triggered with the new value of ng-model because setting change:0 made the updateOn events to fire before ng-blur.So basically the output was updated with the new value of ng-model along with myname. 现在,当您使用ng-model-options="{updateOn:'default change blur',debounce:{default:1000,blur:0,change:0}}" ,ng-blur被新值触发因为设置了change:0使得updateOn事件在ng-blur之前触发,所以基本上输出是用ng-model的新值和myname来更新的。

Working Example : https://plnkr.co/edit/9wdA0he2YVcsPRLJ1Ant?p=preview 工作示例https : //plnkr.co/edit/9wdA0he2YVcsPRLJ1Ant?p=preview

This is because when you set debounce the digest loop is triggered after the given time. 这是因为当您设置debounce ,摘要循环会在给定时间后触发。 After the digest loop is triggered It checks whether a value has changed that hasn't yet been synchronized across the app. 触发摘要循环后,它将检查尚未在应用程序之间同步的值是否已更改。

In your case the input value will be synchronized with the model variable myname after 1000ms or 1s but immediate update when removing the focus. 在您的情况下,输入值将在1000ms或1s之后与模型变量myname同步,但是在删除焦点时立即更新。 Your method onBlur(myname) is called with the previous value of myname , because at the time function was called it still has the previous value of the argument passed to it (it can't update the value of myname and call the function at same time) and after that the digest loop update myname . 你的方法onBlur(myname)被调用以前的值myname ,因为当时函数被调用它仍然具有传递给它的参数的前值(它不能更新MYNAME的价值和调用函数在同时间) ,然后摘要循环更新myname You may check that the model is update immediatly by putting {{myname}} next to the inputs. 您可以通过在输入旁边放置{{myname}}来检查模型是否立即更新。

ng-blur 
   -> call onBlur(myname)
      -> here myname is with old value still
      -> trigger digest loop (here is where the new value is assigned to myname) 
         -> update model & view

{updateOn: 'event'} specifies that the binding should happen when the specific event occur. {updateOn:'event'}指定在发生特定事件时应进行绑定。

To update the model before your element lose focus (onblur) you have to use updateOn: change and set its time to 0, that's how on each change angular will immediatly bind the new value to your function param. 要在元素失去焦点(模糊)之前更新模型,您必须使用updateOn: change并将其时间设置为0,这就是在每次更改角度时,角度将立即将新值绑定到函数参数。

After some research we came across this configuration 经过研究,我们发现了这种配置

ng-model-options="{updateOn:'default change blur',debounce:{default:1000,blur:0,change:0}}"

Which works fine! 哪个很好! as expected on ng-blur event it returns updated value. 如预期的ng-blur事件,它将返回更新的值。

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

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