观察者需要观察一些值并检测到该值已更改。
在调用或新的观察者之后,将其添加到当前范围内的内部观察者集合中。$watch()$watchCollection
Watcher是一个简单的函数,在每个摘要循环中调用它,并返回一些值。Angular检查返回的值(如果它与上一次调用的值不同)-在第二个参数中传递给函数或将被执行的回调。$watch()$watchCollection
(function() { angular.module("app", []).controller("ctrl", function($scope) { $scope.value = 10; $scope.$watch( function() { return $scope.value; }, function() { console.log("value changed"); } ); } })();
观察者是性能杀手。观察者越多,他们进行摘要循环所需的时间就越长,UI越慢。如果观察者检测到更改,它将启动摘要循环(在所有屏幕上重新计算)
可以通过三种方式手动监视Angular中的变量更改。
$watch() -只看价值变化
$watchCollection() -观看收藏中的变化(观看次数超过常规的$watch)
$watch(..., true)-尽可能避免这种情况,它将执行“深度监视”并终止性能(监视数量超过watchCollection)
请注意,如果要在视图中绑定变量,那么您正在创建新的观察者-{{::variable}}请勿创建观察者,尤其是在循环中
结果,您需要跟踪您正在使用多少个观察者。您可以使用此脚本来统计观看者(记入@Words Like Jared-如何计算页面上的观看总数?
(function() { var root = angular.element(document.getElementsByTagName("body")), watchers = []; var f = function(element) { angular.forEach(["$scope", "$isolateScope"], function(scopeProperty) { if(element.data() && element.data().hasOwnProperty(scopeProperty)) { angular.forEach(element.data()[scopeProperty].$$watchers, function(watcher) { watchers.push(watcher); }); } }); angular.forEach(element.children(), function(childElement) { f(angular.element(childElement)); }); }; f(root); // 删除重复的观察者 var watchersWithoutDuplicates = []; angular.forEach(watchers, function(item) { if(watchersWithoutDuplicates.indexOf(item) < 0) { watchersWithoutDuplicates.push(item); } }); console.log(watchersWithoutDuplicates.length); })();
如果您不想创建自己的脚本,则可以使用一个名为ng-stats的开源实用程序,该实用程序使用嵌入到页面中的实时图表来了解Angular正在管理的手表数量以及消化周期的频率和持续时间。该实用程序公开了一个名为的全局函数showAngularStats,您可以调用该函数来配置希望图表的工作方式。
showAngularStats({ "position": "topleft", "digestTimeThreshold": 16, "autoload": true, "logDigest": true, "logWatches": true });
上面的示例代码自动在页面上显示以下图表(交互式演示)。