究竟什么时候调用 ng-checked
When exactly is ng-checked called
在使用 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
之间的关系吗?以及如何避免这种情况?
ng-checked,就像许多 angular 的指令一样,都是基于 watches 的。每当调用摘要循环时,它都会评估所有观察者(您正在使用的功能是其中之一)。所以每次 $timeout 评估它都会开始一个新的 $digest 循环并评估所有观察者。这是 "magic" 的一部分,它使视图使用控制器和指令中的所有数据进行更新。
如果您使函数变得复杂,或者创建大量观察者,观察者可能会成为性能问题。通常最好有简单的逻辑 returns true 或 false 非常快,并避免对所有内容设置监视。
原因一言以蔽之:digest cycle。由于您的函数绑定到视图,每次摘要循环发生时,这些表达式都会作为脏检查的一部分进行评估,以确保相应的 DOM 是否需要更新。这与 angular material 无关,它是核心 angular 实现。现在在你的情况下你正在无限地调用 $timeout
这意味着在每次超时执行后 digest
循环恰好执行脏检查。
现在你所拥有的很好,但是每当你 bind
函数到 DOM (作为视图绑定、插值或 属性 状态属性甚至 DOM 过滤器 - 当然事件很好)你应该 意识到这样一个事实,即随着应用程序的增长,你不会无意或有意地在该功能中执行大量操作 ,它会减慢整个应用程序,并且当应用程序变得更大并且问题开始发生时,将很难重构和诊断。尽可能绑定到 属性 而不是函数。请注意,即使您绑定 属性 仍然 angular $parse
在其上创建一个 getter 并将其添加到 $$watchers
队列以在每个摘要周期进行脏检查, 但区别在于它是一个简单的 getter 函数。
所以基本上,例如在您的情况下,您可以将 ng-checked
绑定到 属性
..ng-checked="doesExist"
并在需要更新时设置属性 doesExist
。因此,您不必每次都检查是否存在,而是在相应事件发生时明确设置相应的 属性。这也使逻辑明确。
在使用 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
之间的关系吗?以及如何避免这种情况?
ng-checked,就像许多 angular 的指令一样,都是基于 watches 的。每当调用摘要循环时,它都会评估所有观察者(您正在使用的功能是其中之一)。所以每次 $timeout 评估它都会开始一个新的 $digest 循环并评估所有观察者。这是 "magic" 的一部分,它使视图使用控制器和指令中的所有数据进行更新。
如果您使函数变得复杂,或者创建大量观察者,观察者可能会成为性能问题。通常最好有简单的逻辑 returns true 或 false 非常快,并避免对所有内容设置监视。
原因一言以蔽之:digest cycle。由于您的函数绑定到视图,每次摘要循环发生时,这些表达式都会作为脏检查的一部分进行评估,以确保相应的 DOM 是否需要更新。这与 angular material 无关,它是核心 angular 实现。现在在你的情况下你正在无限地调用 $timeout
这意味着在每次超时执行后 digest
循环恰好执行脏检查。
现在你所拥有的很好,但是每当你 bind
函数到 DOM (作为视图绑定、插值或 属性 状态属性甚至 DOM 过滤器 - 当然事件很好)你应该 意识到这样一个事实,即随着应用程序的增长,你不会无意或有意地在该功能中执行大量操作 ,它会减慢整个应用程序,并且当应用程序变得更大并且问题开始发生时,将很难重构和诊断。尽可能绑定到 属性 而不是函数。请注意,即使您绑定 属性 仍然 angular $parse
在其上创建一个 getter 并将其添加到 $$watchers
队列以在每个摘要周期进行脏检查, 但区别在于它是一个简单的 getter 函数。
所以基本上,例如在您的情况下,您可以将 ng-checked
绑定到 属性
..ng-checked="doesExist"
并在需要更新时设置属性 doesExist
。因此,您不必每次都检查是否存在,而是在相应事件发生时明确设置相应的 属性。这也使逻辑明确。