的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会被调用,但只有一次.
如果使用Angular v1.1.5并使用ng-if而不是ng-show,则会有相同的行为,但如果使用ng-init,则会正确调用$scope.ready一次.在我的情况下,我将需要ng-show或ng-if.
普兰克:http://plnkr.co/edit/ZSwVNLeFSuhbouXZu9SM?p=preview
澄清:
为了详细说明我的目标,让我们说$scope.ready在某些时候稍后会返回false(也许它会调用AJAX,不应该多次调用),我希望“一些内容”不再是可见的.也就是说,动态行为基于$scope.ready的结果.
有任何想法吗?感谢您的帮助!
解决方法
在每个摘要周期,对于每个监视,AngularJS评估关联的表达式以查看是否有任何更改,如果有,则调用监听器(在ng-show / ng-hide的情况下,监听器将显示或隐藏基于元素的元素)关于ready()返回的值.
现在,AngularJS不仅可以满足ready()返回的第一个值,因为在同一个摘要周期中,某些东西(例如另一个监视表达式)可能实际上会进行一些更改,导致ready()返回的值变为不同的值(例如,通过改变ready()返回的isReady变量).显然,开发人员希望将最新值反映到DOM中.
因此,AngularJS将至少对每个手表表达式进行一次评估,以确保在完成摘要周期之前将其“稳定”.当然,如果表达式不断变化,这会导致无限的摘要迭代,因此如果摘要周期无法在10次迭代内完成,AngularJS将抛出错误.