为什么Angular在使用表达式时不更新ng-show状态?

时间:2014-09-19 19:45:38

标签: javascript angularjs angularjs-scope ng-show angularjs-ng-show

当我使用范围变量时,让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(...)为真)。但似乎Angular没有对这个表达式的价值做任何事情!

alert dialog box shows that isEmpty is being called and correctly returning false

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

1 个答案:

答案 0 :(得分:0)

似乎{{}}符号表示仅Angular 评估并使用 大括号内的表达式一次。

听起来Angular在过去一年左右改变了对括号的处理,或者我使用的博客条目是错误的:http://www.whitneyland.com/2013/02/why-does-angularjs-sometimes-use-single-braces-sometimes-double-braces-and-sometimes-no-braces.html

评论员Cyril DD,Razah和Mohammad Sepahvand,感谢指出放弃{{}}解决了我的问题。

我仍然非常惊讶Angular似乎不止一次 评估 这个表达式 - 实际上很多次都是12或者12的证据所以我必须解雇从isEmpty调用的alert()!

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