在使用AngularMaterial时,我有ng-checked
这样:
<md-list>
<md-list-item ng-repeat="option in options">
<p> {{ option }} </p>
<md-checkbox class="md-secondary" aria-label="{{$index}}" ng-checked="exists($index)" ng-click="toggle($index)"></md-checkbox>
</md-list-item>
</md-list>
我的存在功能:
$scope.exists = function (optionNum) {
console.log('Inside $scope.exists. option: '+optionNum);
};
我的计时器:
function updateTimer() {
var onTimeout = function(){
mytimeout = $timeout(onTimeout,1000);
}
var mytimeout = $timeout(onTimeout,1000);
}
这样,$scope.exists
函数每秒都会调用一次。有人可以解释ng-checked
和$timeout
的关联方式吗?以及如何避免这种情况?
答案 0 :(得分:2)
ng-checked,就像许多角度指令都是基于手表一样。无论何时调用摘要循环,它都会评估所有观察者(您正在使用的函数是其中之一)。因此,每次$ timeout评估时,它都会启动一个新的$ digest周期并评估所有观察者。这是“魔术”的一部分,它使视图与控制器和指令中的所有数据一起更新。
如果你使你的功能变得复杂,或者让TONS成为观察者,那么观察者就会成为一个性能问题。通常最好有一个简单的逻辑,可以非常快速地返回true或false,并避免在所有内容上设置监视。
答案 1 :(得分:2)
一个词中的原因是:digest cycle。由于您的函数绑定到视图,因此每次摘要周期发生时,这些表达式都会作为脏检查的一部分进行评估,以确保是否需要更新相应的DOM。这与角度材料无关,它是核心角度实现。现在,在您的情况下,您无限地调用$timeout
,这意味着在每次超时后执行digest
周期都会执行脏检查。
现在你拥有的很好,但每当你bind
DOM的一个函数(作为视图绑定,插值或属性状态属性甚至DOM过滤器的一部分 - 当然事件都很好)你应该<强烈>意识到您在应用程序增长时不会意外或故意执行该功能的大量操作,这会降低整个应用程序的速度,并且当应用程序变大并且很难重构和诊断时问题开始发生。尽可能绑定到属性而不是函数。请注意,即使您绑定了一个属性,仍然会在$parse
上创建一个getter并将其添加到$$watchers
队列,以便在每个摘要周期进行脏检查,但区别在于它是一个简单的getter函数。
所以基本上在你的情况下你可以将ng-checked
绑定到属性
..ng-checked="doesExist"
并在需要更新时设置属性doesExist
。因此,不是每次都检查存在,而是在相应事件发生时显式设置相应的属性。这也使得逻辑显而易见。