Javascript 为什么我的Angular.js控制器在下面的代码中执行它的函数两次?

Javascript 为什么我的Angular.js控制器在下面的代码中执行它的函数两次?,javascript,angularjs,controller,Javascript,Angularjs,Controller,我有一个ng repeat循环通过属于SomeController的对象数组: <div ng-controller="SomeController as aCtrl"> <div ng-repeat="category in aCtrl.categories"> <p ng-show="aCtrl.checkShouldBeDisplayed(category)">{{category.name}}</p> </div>

我有一个
ng repeat
循环通过属于
SomeController
的对象数组:

<div ng-controller="SomeController as aCtrl">
  <div ng-repeat="category in aCtrl.categories">
    <p ng-show="aCtrl.checkShouldBeDisplayed(category)">{{category.name}}</p>
  </div>
</div>

我希望
checkshouldblayed
函数计数为4,因为
SomeController.categories
数组中有四个元素。相反,它计数为8-在这里检查:(您需要查看浏览器中的控制台以查看日志)。我怎样才能避免这种行为?干杯

这是意料之中的;指令
ng repeat
将重复框架认为正确的次数;这称为脏检查,您可以在中阅读更多关于它的内容


出于这个原因,最好是陈述式思考,而不是强制性思考。换句话说,方法
checkshouldblayed
应该只执行tin上显示的操作,而不依赖于调用它的次数。如果需要执行某种聚合或操作,则应在控制器的其他位置执行。

这是意料之中的;指令
ng repeat
将重复框架认为正确的次数;这称为脏检查,您可以在中阅读更多关于它的内容

出于这个原因,最好是陈述式思考,而不是强制性思考。换句话说,方法
checkshouldblayed
应该只执行tin上显示的操作,而不依赖于调用它的次数。如果需要执行某种聚合或操作,则应在控制器的其他位置执行。

根据

每次调用$digest()时都会调用watchExpression,并应返回将被监视的值。(由于$digest()在检测到更改时会重新运行,因此watchExpression可以每$digest()执行多次,并且应该是幂等的。)
[…]
监视侦听器可能会更改模型,这可能会触发其他侦听器。这是通过重新运行观察程序直到检测不到任何更改来实现的

而ngShow所做的一切就是注册一个观察者:

scope.$watch(attr.ngShow, function ngShowWatchAction(value){
    $animate[toBoolean(value) ? 'removeClass' : 'addClass'](element, 'ng-hide');
});
您的函数是
ngShow
的监视表达式,因此执行两次:
1.在第一个$digest中,它检测新值。
2.在第二个$digest中,它验证没有任何更改并终止


在此中,您可以验证有两个$digest循环。

根据

每次调用$digest()时都会调用watchExpression,并应返回将被监视的值。(由于$digest()在检测到更改时会重新运行,因此watchExpression可以每$digest()执行多次,并且应该是幂等的。)
[…]
监视侦听器可能会更改模型,这可能会触发其他侦听器。这是通过重新运行观察程序直到检测不到任何更改来实现的

而ngShow所做的一切就是注册一个观察者:

scope.$watch(attr.ngShow, function ngShowWatchAction(value){
    $animate[toBoolean(value) ? 'removeClass' : 'addClass'](element, 'ng-hide');
});
您的函数是
ngShow
的监视表达式,因此执行两次:
1.在第一个$digest中,它检测新值。
2.在第二个$digest中,它验证没有任何更改并终止



在此中,您可以验证有两个$digest循环。

好的,谢谢。为什么这里有两个
$digest
循环?这是因为@Mendhack所说的肮脏检查吗?是的,这在我的答案中(查找
1.
2.
):)好的,谢谢。为什么这里有两个
$digest
循环?这是因为@Mendhack所说的肮脏检查吗?是的,这是在我的答案中(查找
1.
2.
):)对,这似乎使事情变得复杂。我在这里试图做的是覆盖正常的
ng show
行为,该行为通过控制器上定义的其他状态绑定到模型的状态(想象拥有
SomeController.firstUse=true
(而不是计数器),一旦用户与控制器交互,它将重置为
false
。您能推荐一种角度的方法来执行此操作吗?如果交互是指单击或鼠标移动,您可以使用
ng click
ng mouseover
并调用一种方法,该方法将
firstUse
设置为
false
。如果交互仅仅涉及到looki在这里,您可以在(“$destroy”上的
$scope.$on”中执行此操作…
您将其设置为
false
。如果这不是您的意思,请编辑您的问题并添加您的总体目标。然后我们可以建议不同的方法。对,这似乎使事情变得复杂。我在这里尝试的是覆盖正常的
ng show
行为,它通过控制器上定义的其他一些状态(假设使用
SomeController.firstUse=true
(而不是计数器),一旦用户与控制器交互,它将重置为
false
。您能推荐一种角度的方法来执行此操作吗?如果交互是指单击或鼠标移动,您可以使用
ng click
ng mouseover
并调用一种方法,该方法将
firstUse
设置为
false
。如果交互仅仅涉及到looki你可以在
$scope.$on(“$destroy”…
中将其设置为
false
。如果这不是你的意思,请编辑你的问题并添加你的总体目标。然后我们可以建议不同的方法。