控制器功能使用ng-show调用两次

时间:2013-09-02 21:46:11

标签: javascript angularjs angularjs-scope

我有一个非常简单的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}}。

的结果

有什么想法吗?谢谢你的帮助!

对于记录thisthis不是同一个问题。

2 个答案:

答案 0 :(得分:14)

这是设计的,而不是bug(它与AngularJS编译器无关,因为另一个答案错误地陈述)。 ng-showng-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

的信息

错误报告:https://github.com/angular/angular.js/issues/1146