为什么Angular在我的代码中循环了这么多次?

时间:2014-01-12 14:44:36

标签: angularjs

我对Angular很新。我有一些使用ng-repeat的代码。

这是html:

<div ng-controller="myCtrl">
  <h2>Testing ng-repeat and sortable table</h2>
  <table>
    <tbody ui-sortable ng-model="list">
      <tr ng-repeat="item in list" style="cursor: move;">
        <td>{{log("ng-repeat on table with sorting:",$index); "index: " + $index + " array-item: " + item}}</td>
      </tr>
    </tbody>
  </table>

  <h2>Testing ng-repeat</h2>
  <div ng-repeat="item in list">
    {{log("ng-repeat on div",$index); "index: " + $index + " array-item: " + item}}
  </div>
</div>

这是控制器:

myapp.controller('myCtrl', function ($scope) {
  $scope.list     = ["a0","a1"];
  var count       = 0;

  $scope.log = function(title,index) {
    ++count;
    console.log(title, "count:", count, "index:", index);
  };
});

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

我原本希望在日志(控制台)中看到4行,但是有12行,如下所示:

ng-repeat on table with sorting: count: 1 index: 0
ng-repeat on table with sorting: count: 2 index: 1
ng-repeat on div count: 3 index: 0
ng-repeat on div count: 4 index: 1
ng-repeat on table with sorting: count: 5 index: 0
ng-repeat on table with sorting: count: 6 index: 1
ng-repeat on div count: 7 index: 0
ng-repeat on div count: 8 index: 1
ng-repeat on table with sorting: count: 9 index: 0
ng-repeat on table with sorting: count: 10 index: 1
ng-repeat on div count: 11 index: 0
ng-repeat on div count: 12 index: 1 

为什么不只有4行(两个ng重复循环的数字)?

2 个答案:

答案 0 :(得分:2)

这就是角度的作用方式。它被称为摘要循环,每次在范围内发生变化时都会执行。 ng-repeat有点复杂,实际理解为什么会发生这种情况的唯一方法是挖掘资料来源。 即使您没有更改范围内的任何内容,ng-repeat也会在其范围内发生很大变化,并会执行大量$watch$apply触发$digest循环。我开始调试开发版的angular(https://github.com/angular/angular.js/blob/34fee06ca7db16549764f53c0382f2b6e2482201/src/ng/directive/ngRepeat.js#L3)。

答案 1 :(得分:2)

这是预期的行为。 ng-repeat两次调用log方法(摘要周期)。 Angular 观察以确定DOM结构的哪些部分已重新绘制。

如果您想避免这种情况,请使用$watch并在新值等于旧值时删除所有结果。

类似的东西:

$scope.$watch('list', function(items) {
   for(var i = 0; i < items.length; i++) {
     var item = items[i];
    $scope.log("ng-repeat on table with sorting:",i);
   }
}, true);