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