angular.js在包装ng-repeat时尝试多次迭代

时间:2013-08-21 06:16:49

标签: angularjs

在SO Angular.js ng-repeat: opening/closing elements after x iterations

上遵循此答案的基本概念后

我正在对项目进行分组并将它们包装在div中,并收到以下错误Error: 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations:

这让我相信Angular期待10次重复并且只注册5.但是,输出看起来正确,所有10个项目都显示出来。

我正在构建一个Windows启动屏幕类型布局,其中一些图块将是单个,其他图块是双倍宽度。我正在做一些计算来将瓷砖包裹在div中。

我构建的过滤器是

app.filter('partition', function() {
  var part = function(arr, size) {
    if ( 0 === arr.length ) return [];
    var applist=[];
    var partlist=[];
    var blocksize=0;
    console.log(arr);
    for(var a in arr){
        var app = arr[a];

        if(app.width=='single'){
            console.log(app.name);
            partlist.push(app);
            blocksize++;
        }
        if(app.width=='double' && blocksize=4){
            applist.push(partlist);
            partlist=[app];
            blocksize=2;
        }

        if(blocksize==size || a==arr.length-1){
                applist.push(partlist);
                partlist=[];
                blocksize=0;
            }
    }
    console.log(applist)
   return applist;
  };
  return part;
});

和带有ng-repeats的html是

<div ng-repeat="block in apps | filter:search | partition:6" class="app-block" >
    <li ng-repeat="app in block" class="app-tile" ng-class="{double:app.width=='double'}">
          <div class="name">{{app.name}}</div>
    </li>
</div>

我使用嵌套重复错了吗?正如我所说,显示的瓷砖数量是正确的,但错误是关于我的(它是大的,丑的和红色的)。

1 个答案:

答案 0 :(得分:4)

这里的根本问题是你的partition过滤器返回一个数组数组;每个摘要周期,它返回一个不同的数组数组,即使内部内部数组的元素是相同的。

例如,在JavaScript控制台中检查此表达式:

[[1, 2], [3, 4]] == [[1, 2], [3, 4]] // false

因为ngRepeat认为每次都有不同的数组,所以它会继续重新运行一个摘要周期,直到它达到最大值10。

如果您有一个Plunker或JSFiddle,它可以提供更完整,更有效的问题解决方案,那将有助于展示解决方案;取而代之的是,查看this answer以及该问题的接受答案。

您可以做的一件事就是操纵控制器中的数据并迭代它:

app.controller('SomeController', function($scope, $filter) {
  $scope.apps = [ ... ];

  var calculateBlocks = function() {
    var filteredBlocks = $filter('filter')($scope.search);
    $scope.appsBlocks = $filter('partition')(filteredBlocks, 6);
  };

  // Every time $scope.apps changes, set $scope.appsBlocks
  // to the filtered and partitioned version of that data.
  // In AngularJS 1.4+ you can use $watchCollection:
  // http://code.angularjs.org/1.1.4/docs/api/ng.$rootScope.Scope#$watchCollection
  $scope.$watch('apps', calculateBlocks, true);
  // Same if the search term changes.
  $scope.$watch('search', calculateBlocks);
});

然后在你的HTML中:

<div ng-repeat="block in appsBlocks" class="app-block" >
  <li ng-repeat="app in block" class="app-tile" ng-class="{double:app.width=='double'}">
    <div class="name">{{app.name}}</div>
  </li>
</div>