3

当我使用作用域变量时,让 ng-show 工作没有问题:

(摘自html文件:)

<li ng-show="hasBattery">
  <span>Battery</span>
  <dl>
    <dt>Type</dt>
    <dd>{{phone.battery.type}}</dd>
  </dl>
</li>

使用以下控制器代码,它工作正常:

phonecatControllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams', '$http',
  function($scope, $routeParams, $http) {

    function loadData() {
      // fyi, the ?date nonsense below is to avoid browser cacheing of the json file 
      $http.get('phones/' + $routeParams.phoneId + '.json' + '?' + 
                new Date().getTime()).success(function(data) {
        $scope.phone = data; 
        $scope.hasBattery = !$scope.isEmpty($scope.phone.battery.type);
        // should i call some form of $scope.$apply() here? when i do,
        // i get a digest already in progress error. ng-show seems to 
        // update fine without a call to $apply
      });
    };

    $scope.isEmpty = function(str) {
      var retVal = (typeof(str) === undefined || !str || 0 === str.length);
      alert("isempty: returning " + retVal);
      return retVal;
    };

    $scope.hasBattery = false;
    loadData();
  }
]);

就像我说的,这行得通。当我查看 phone.battery.type 未定义或空白的页面时,ng-show 正确隐藏了 div。当我查看 phone.battery.type 是非空字符串的页面时,ng-show 正确显示了 div。都好。

这是我的问题:当我直接在 ng-show 表达式中使用 !isEmpty(...) 调用,而不是使用 $scope.hasBattery 作为中介时,它不起作用。

这是我的那个版本的代码:

<li ng-show="{{!isEmpty(phone.battery.type)}}">
  <span>Battery</span>
  <dl>
    <dt>Type</dt>
    <dd>{{phone.battery.type}}</dd>
  </dl>
</li>

控制器,移除了 hasBattery:

phonecatControllers.controller('PhoneDetailCtrl', ['$scope', '$routeParams', '$http',
  function($scope, $routeParams, $http) {

    function loadData() {
      $http.get('phones/' + $routeParams.phoneId + '.json' + '?' + new Date().getTime()).success(function(data) {
        $scope.phone = data; 
        // no longer do any evaluation of isEmpty here.
        // as before, I'm not calling $scope.$apply() at all
      });
    };

    // same code as before
    $scope.isEmpty = function(str) {
      var retVal = (typeof(str) === undefined || !str || 0 === str.length);
      alert("isempty: returning " + retVal);
      return retVal;
    };

    loadData();
  }
]);

当我加载一个 phone.battery.type 是非空字符串的页面时,我希望 ng-show 显示它,它无法显示 div。我看到 isEmpty 确实在数据加载后被调用,并且正确返回 false(因此 ng-show 的表达式 !isEmpty(...) 为 true)。但似乎 Angular 并没有对这个表达式的值做任何事情!

警报对话框显示正在调用 isEmpty 并正确返回 false .

知道发生了什么吗?我认为这是一个 $scope.$apply 问题,就像我在 SO 的其他地方看到的那样,但似乎确实正在使用最新数据评估表达式。

4

1 回答 1

0

似乎 {{ }} 表示法意味着 Angular 只计算和使用大括号内的表达式一次。

听起来Angular在去年左右改变了它对大括号的处理,或者我一直在使用的这个博客条目是错误的:http: //www.whitneyland.com/2013/02/why-does-angularjs-sometimes-使用单大括号-有时-双大括号-有时-无大括号.html

评论者 Cyril DD、Razah 和 Mohammad Sepahvand,感谢您指出删除 {{ }} 解决了我的问题。

我仍然很惊讶 Angular 似乎不止一次地评估表达式 - 事实上,很多次,作为证据,我不得不关闭从 isEmpty 调用的 alert() 的 12 次左右!

为什么 Angular 会评估一个它知道它不会做任何事情的表达式?

于 2014-09-22T15:15:07.233 回答