angularjs - 当 $interval 触发时,ng-show 不会更新 class

angularjs - ng-show doesn't update class when $interval triggers

尝试使用 angular 中的 $interval 来使用 ng-show 更改列表中当前可见的项目。检查 html,我注意到 angular 从 true/false 更改了 ng-show,但它没有删除 ng-hide class。 html 很简单:

<h1>Hello Plunker!</h1>
<div ng-controller="MyCtrl">
  <div>Iterator: {{i}}</div>
  <ul>
    <li ng-repeat="d in data" ng-show="{{i == $index}}">{{i}} - {{$index}} - {{d}}</li>
  </ul>
</div>

app.js 也很基础:

(function(){  
   var app = angular.module('MyApp', ['my-controller']);
})();

和我的module/controller

(function(){
  var app = angular.module('my-controller', []);

  app.controller('MyCtrl', ['$scope', '$interval', function($scope, $interval){
    $scope.data = [111, 222, 333, 444];
    $scope.i = 0;
    var timeoutId;


    timeoutId = $interval(function(){
      $scope.i ++;  
      if ($scope.i >= $scope.data.length)
        $scope.i = 0;
    },
    1000);


  }]);
})();

Here's my plnkr

这是因为您在 ng-show 表达式中使用插值 ({{i == $index}}) 设置字符串 "true"/"false",而不是直接提供表达式。

ng-show="i == $index"

Plnkr

只是为了补充说明,看看 ng-show source code

 scope.$watch(attr.ngShow, function ngShowWatchAction(value) {
    // we're adding a temporary, animation-specific class for ng-hide since this way
    // we can control when the element is actually displayed on screen without having
    // to have a global/greedy CSS selector that breaks when other animations are run.
    // Read: https://github.com/angular/angular.js/issues/9103#issuecomment-58335845
    $animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS, {
      tempClasses: NG_HIDE_IN_PROGRESS_CLASS
    });
  });

它在属性值上注册了一个监视,所以当使用插值(首先渲染)时,它实际上为第一个项目设置了监视 "true",为最后三个设置了 "false"(作为预期的)。一切都很好,手表第一次运行以进行脏检查,它被解析为布尔值,并将 ng-hide class 添加到最后 3 个,第一个仍然显示。所以直到现在 watch 设置在范围上的字符串 "true/false" 上并且它永远不会改变并且 watch 不再执行(因为它总是 return 在摘要周期中由超时触发的相同值case) 和 items shows 保持显示状态,hidden 保持隐藏状态,因为它永远没有机会执行 add/removeClass。现在,当您使用表达式时,每次摘要发生时都会对其进行评估,布尔标志评估为表达式的值发生变化并且观察者被执行并且 class 按预期获得 added/removed。