我有一个非常简单的Angular应用程序设置,代码如下:
的index.html
<!DOCTYPE html>
<html>
<head>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js'></script>
<script src='app.js'></script>
</head>
<body ng-app="app">
<div ng-controller="MyCtrl">
<div ng-show="ready()">
Some content
</div>
</div>
</body>
</html>
app.js
var app = angular.module('app', []);
app.controller('MyCtrl', function($scope) {
console.log("MyCtrl called")
$scope.ready = function() {
console.log("ready called");
return true;
}
})
如果在控制台打开的情况下运行此操作,您将看到 MyCtrl称为一次,就绪,称为两次。我花了好几个小时试图解决这个问题,我认为$scope.ready
没有理由被称为ng-if
,只有一次。
如果您使用Angular v1.1.5并使用ng-show
代替ng-init
,则会有相同的行为,但如果您使用$scope.ready
,则会正确调用ng-show
一个时间。在我的情况下,我需要ng-if
或$scope.ready
。
Plunkr:http://plnkr.co/edit/ZSwVNLeFSuhbouXZu9SM?p=preview
澄清:
为了详细说明我的目标,让我们说false
稍后返回$scope.ready
(也许它会进行AJAX调用,不应该多次调用),我想“有些内容“不再可见。也就是说,动态行为基于{{1}}。
有什么想法吗?谢谢你的帮助!
答案 0 :(得分:14)
这是设计的,而不是bug(它与AngularJS编译器无关,因为另一个答案错误地陈述)。 ng-show
和ng-hide
通过“观察”表达式ready()
的更改来工作。
在每个摘要周期,对于每个监视,AngularJS评估关联的表达式以查看是否有任何更改,如果有,则调用监听器(在ng-show
/ ng-hide
的情况下),监听器将根据ready()
返回的值显示或隐藏元素。
现在,AngularJS不仅可以满足ready()
返回的第一个值,因为在同一个摘要周期中,某些内容(例如另一个监视表达式)实际上可能会进行一些更改,从而导致{{1成为一个不同的值(例如,通过改变由ready()
返回的isReady
变量)。显然,开发人员希望将最新值反映到DOM中。
因此,AngularJS将至少评估一次每个监视表达式,以确保它在完成摘要周期之前“稳定”。当然,如果表达式不断变化,这会导致无限的摘要迭代,因此如果摘要周期无法在10次迭代中完成,AngularJS将抛出错误。
答案 1 :(得分:3)
有关于此的错误报告,响应与编译器执行双重检查
有关这是预期的行为。 AngularJS执行两次调用以确保模型在渲染之前已稳定。
应该有更多关于为什么在这里 http://docs.angularjs.org/guide/compiler
的信息