ng-model-options 如何帮助减少事件摘要周期?
是的,ng-model-options 可以帮助您限制$digest 循环的数量。如果您只使用 ng-model 而不为其设置任何选项,那么您的 $digest 循环将针对 ng-model 值的每次更改运行。如果$digest 循环充满了要进行脏检查的数据,则用户将在(例如)在 .Here 中输入时看到 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 <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 循环发生的方式和时间。
让我们通过引入 debounce 来更好地控制 $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。
debounce 的默认值和更改有什么区别?
去抖动对象属性的默认值和更改只是事件。默认不是 DOM 事件,这只是 ng-model-options api 的一部分。假设你正在设置你的 ngModelOptions 像
ng-model-options="{
updateOn: 'default'
}"
那么您的输入字段的行为将不会从默认行为发生变化。在我们将它与 debounce like 结合使用之前,此配置并不是真正有用的
ng-model-options="{
updateOn: 'default',
debounce: { 'default': 500 }
}"
这将使输入在 500 毫秒后更新。所以基本上这回答了默认值是什么。您可以使用其他 DOM 事件(例如 change,blur,mouseover...等)进行反跳。
更新:
当您使用ng-model-options="{updateOn:'default blur',debounce:{default:1000,blur:0}}" 时,ng-blur 被 ng-model 的旧值触发,之后仅触发 updateOn 事件。所以基本上输出将包含 ng-model 的旧值,尽管我的名字将被更新。
工作示例: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 的新值触发,因为设置 change:0 使得 updateOn 事件在 ng-blur 之前触发。所以基本上输出更新为ng-model 的新值以及 myname。
工作示例:https://plnkr.co/edit/9wdA0he2YVcsPRLJ1Ant?p=preview