2

我已经申请ng-model-optionsinput以下配置

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

根据应用的配置,ng-model-options我期待事件的更新ng-model's值,但尽管为模糊事件设置了去抖动值,ng-blur但它不会返回新值。0

default*注意:仅当用户在去抖动中给出的时间之前集中注意力时才会出现此问题,即1000

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:

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

Plunker 链接:https ://embed.plnkr.co/XJMUUD/

为什么去抖动不起作用?如果我做错了,请纠正我!

提前致谢 :)

我也已经给出了我的问题的答案!让我知道它如何灵活使用,以及它如何帮助减少事件摘要周期。

4

3 回答 3

9

ng-model-options 如何帮助减少事件摘要周期?

是的, ng-model-options可以帮助您限制$digest循环次数。如果您只使用 ng-model 而不为其设置任何选项,那么您的 $digest 循环将针对 ng-model 值的每次更改运行。如果$digest循环中充满了要进行脏检查的数据,则用户将在 UI 中看到滞后,同时(例如)在 .Here 中引用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>

从我们的标准输入中可以看出,我们$digest在输入字段中键入的每个字符都会触发循环。这可能会导致大型应用程序的最终用户延迟。

现在我们将看到带有 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>

在这里我们可以看到$digest只有当我们失去输入焦点时才会触发循环。因此,基本上,ngModelOptions我们可以控制$digest周期发生的方式和时间。

让我们通过引入去抖动来更好地控制$digest周期,以便我们可以告诉 Angular 何时更新。

// 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>

上面说明了默认值将在事件停止后 250 毫秒更新,并且当用户离开输入时,模糊将立即更新(如果这是我们想要的所需行为)。

再次开始打字,然后停下来,注意$digest计数比最初的演示要低得多。然后,您可以单击/制表以$digest立即呼叫另一个。


默认和去抖动的变化有什么区别?

去抖动对象属性的默认值和更改只不过是事件。默认不是 DOM 事件,这只是 ng-model-options api 的一部分。假设你正在设置你的 ngModelOptions

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

然后,您的输入字段的行为与默认行为没有任何变化。在我们将它与 debounce 结合起来之前,这个配置并不是真正有用的

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

这将使输入在 500 毫秒后更新。所以基本上这回答了默认值是什么。您可以使用其他 DOM 事件,例如change,blur,mouseover...etc 来进行去抖动。


更新

当你使用ng-model-options="{updateOn:'default blur',debounce:{default:1000,blur:0}}"ng-blur 时,ng-blur 被 ng-model 的旧值触发,之后只触发了 updateOn 事件。所以基本上输出将包含 ng-model 的旧值,尽管 myname 将被更新。

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

现在,当您使用ng-model-options="{updateOn:'default change blur',debounce:{default:1000,blur:0,change:0}}"ng-blur 时,会使用 ng-model 的新值触发 ng-blur,因为设置 change:0 会使 updateOn 事件在 ng-blur 之前触发。所以基本上输出是使用 ng- 的新值更新的模型连同我的名字。

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

于 2017-07-18T12:03:59.497 回答
2

经过一番研究,我们遇到了这个配置

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

哪个工作正常!正如预期的那样,ng-blur它返回更新的值。

于 2017-07-12T08:17:22.763 回答
1

这是因为当你设置debounce摘要循环在给定时间之后触发。触发摘要循环后,它会检查尚未在应用程序中同步的值是否已更改。

在您的情况下,输入值将myname在 1000 毫秒或 1 秒后与模型变量同步,但在移除焦点时会立即更新。您的方法onBlur(myname)是用以前的值调用的myname,因为在调用函数时它仍然具有传递给它的参数的以前的值(它不能更新 myname 的值并同时调用该函数),然后摘要循环更新myname{{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'} 指定绑定应该在特定事件发生时发生。

要在您的元素失去焦点(onblur)之前更新模型,您必须使用updateOn: change并将其时间设置为 0,这就是每次更改角度时如何立即将新值绑定到您的函数参数。

于 2017-07-11T18:43:32.613 回答