6

我有一个非常简单的 Angular 应用程序设置,代码如下:

索引.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 调用了一次,ready 调用了两次。我花了几个小时试图弄清楚这一点,我看不出有什么理由$scope.ready只被称为一次。

如果您使用 Angular v1.1.5 并使用ng-if而不是ng-show您将具有相同的行为,但如果您ng-init正确使用它会调用$scope.ready一次。就我而言,我将需要ng-showor ng-if

Plunkr:http ://plnkr.co/edit/ZSwVNLeFSuhbouXZu9SM?p=preview

澄清: 为了详细说明我的目标,假设$scope.ready稍后返回false(也许它会进行 AJAX 调用,不应多次调用),我希望“某些内容”不再可见。即,基于 的结果的动态行为$scope.ready

有任何想法吗?感谢您的帮助!

记录一下 thisthis不是同一个问题。

4

2 回答 2

14

这是设计使然,而不是错误(它与 AngularJS 编译器无关,正如另一个答案错误地指出的那样)。ng-showng-hide通过“观察”表达式的变化来工作ready()

在每个摘要周期,对于每个 watch,AngularJS 都会评估关联的表达式以查看是否有任何变化,如果有,则调用侦听器(在ng-show/的情况下ng-hide,侦听器将根据返回的值显示或隐藏元素ready()) .

现在,AngularJS 不能只满足于返回的第一个值,ready()因为在同一个摘要周期内,某些东西(例如另一个监视表达式)实际上可能会进行一些更改,导致返回的任何ready()值都是不同的值(例如,通过改变一个isReady变量由ready()) 返回。显然,开发人员希望将最新的值反映到 DOM。

因此,AngularJS 将至少评估每个 watch 表达式一次,以确保在完成一个摘要循环之前它是“稳定的”。当然,如果表达式不断变化,这可能导致无限的摘要迭代,因此如果摘要循环无法在 10 次迭代内完成,AngularJS 将抛出错误。

于 2013-09-03T04:10:39.613 回答
3

对此有一个错误报告,响应与编译器进行双重检查有关

这是预期的行为。AngularJS 调用两次以确保模型在渲染之前已经稳定。

应该有更多关于为什么在这里http://docs.angularjs.org/guide/compiler的信息

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

于 2013-09-02T21:58:31.580 回答