angular.js ng-repeat创build网格

我正在尝试使用bootstrap 3和angularjs创build一个网格。

我试图创build的网格是这样的,重复使用ng-repeat。

<div class="row"> <div class="col-md-4">item</div> <div class="col-md-4">item</div> <div class="col-md-4">item</div> </div> 

我已经尝试使用ng-if ($index % 3 == 0)来添加行,但是这似乎没有工作正确。 任何build议将是伟大的!

谢谢!

编辑:这是我结束了与工作的代码:

 <div ng-repeat="item in items"> <div ng-class="row|($index % 3 == 0)"> <ng-include class="col-sm-4" src="'views/items/item'"></ng-include> </div> </div> 

这是一个古老的答案!

当我写这篇文章的时候,我对Angular还是有点新鲜的。 Shivam有一个更好的答案,我build议你使用。 它将控制器的表示逻辑放在外面,这是一件非常好的事情。

原始答案

您可以随时将您正在重复的列表拆分为控制器中的列表(每个列表有三项)。 所以你列出的是:

 $scope.split_items = [['item1', 'item2', 'item3'], ['item4', 'item5', 'item6']]; 

然后重复它:

 <div ng-repeat="items in split_items" class="row"> <div ng-repeat="item in items" class="col-md-4"> item </div> </div> 

不知道是否有更好的方法。 我也尝试过使用ng-if和ng-switch,但是我永远无法工作。

接受的答案是显而易见的解决scheme,但是呈现逻辑应该保留在视图中而不是在控制器或模型中。 此外,我无法得到OP的解决scheme工作。

当你有一个扁平的项目列表(数组)时,有两种方法可以创build网格系统。 说我们的项目列表是一个字母表:

在这里住宿

 $scope.alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; 

方法1:

这是一个纯粹的angular度解决scheme。

 <div class="row" ng-repeat="letter in alphabet track by $index" ng-if="$index % 4 == 0"> <div class="col-xs-3 letter-box" ng-repeat="i in [$index, $index + 1, $index + 2, $index + 3]" ng-if="alphabet[i] != null"> <div>Letter {{i + 1}} is: <b> {{alphabet[i]}}</b></div> </div> </div> 

外循环每4次迭代执行一次并创build一行。 对于外层循环的每次运行,内层循环重复4次并创build列。 由于无论数组中是否有元素,内部循环都会运行4次,所以如果数组在内部循环完成之前结束, ng-if将确保不会创build多余的列。

方法2:

这是更简单的解决scheme,但需要angular度filter库。

 <div class="row" ng-repeat="letters in alphabet | chunkBy:4"> <div class="col-xs-3 letter-box" ng-repeat="letter in letters" > <div>Letter {{$index + 1}} is: <b> {{letter}}</b></div> </div> </div> 

外循环创build4个字母的组,对应我们的“行”

 [['A', 'B', 'C', 'D'], ['E', 'F', 'G', 'H'], ... ] 

内部循环遍历组并创build列。

注意:方法2可能需要对外部循环的每次迭代进行滤波器评估,因此方法2可能无法很好地适应巨大的数据集。

你可以简单地把你的数组分成你的控制器内部的N个子数组。 示例代码:

 var array = ['A','B','C','D','E','F','G','H']; var chunk = function(arr, size) { var newArr = []; for (var i=0; i<arr.length; i+=size) { newArr.push(arr.slice(i, i+size)); } return newArr; }; $scope.array = chunk(array); 

现在在* .html文件中,你只需要在array ng-repeat

 <div class="row" ng-repeat="chunk in array"> <div class="column" ng-repeat="item in chunk"> {{item}} </div> </div> 

锻炼对我来说:)祝你好运!

有人可能会说,下面的解决scheme不遵循有row div的网格规则,但另一个解决scheme是删除row类(或使用它在ng-repeat ),并使用clearfix类:

 <div class="col-md-12"> <div ng-repeat="item in items"> <div ng-class="{'clearfix': $index%3 === 0}"></div> <div class="col-md-4">{{item}}</div> </div> </div> 

据我所知,这看起来几乎与row相同,但请评论可能的缺陷(除了我上面提到的那个)。

有点迟到的答案,但我用这个,我相信这是更好的一些情况下。 你可以使用Angular Filter包和它的ChunkByfilter来实现这一点。 虽然这个软件包对于这个单独的任务来说是一个繁重的工作,但是对于不同的任务还有其他有用的filter。 我使用的代码是这样的:

 <div class="row mar-t2" ng-repeat="items in posts | chunkBy:3"> <div class="col-md-4" ng-repeat="post in items"> <img ng-src="{{post.featured_url}}" class="img-responsive" /> <a ng-click="modalPop(post.id)"><h1 class="s04-bas2">{{post.title.rendered}}</h1></a> <div class="s04-spotbox2" ng-bind-html="post.excerpt.rendered"></div> </div> </div> 

使用ng-repeat-startng-repeat-end

 <div class="row"> <div ng-repeat-start="item in items track by $index" class="col-sm-4"> {{item}} </div> <div ng-repeat-end ng-if="($index+1) % 3 == 0" class="clearfix"></div> </div> 

易于使用.visible- *类适应不同的媒体查询

 <div class="row"> <div ng-repeat-start="item in items track by $index" class="col-lg-2 col-md-4 col-sm-6"> {{item}} </div> <div ng-repeat-end> <div class="clearfix visible-lg-block" ng-if="($index+1) % 6 == 0"></div> <div class="clearfix visible-md-block" ng-if="($index+1) % 3 == 0"></div> <div class="clearfix visible-sm-block" ng-if="($index+1) % 2 == 0"></div> </div> </div> 

我发现在主要重复块之外有清晰简洁的行pipe理逻辑。 关注点分离 :-)

我使用ngInit稍微不同的方法。 我不确定自从ngInit文档指出这是否是合适的解决scheme

ngInit的唯一适当的用法是为了重用ngRepeat的特殊属性,如下面的演示所示。 除此之外,您应该使用控制器而不是ngInit来初始化作用域上的值。

我不确定这是否属于这种情况,但是我希望将这个function从控制器中移开,以便模板devise者可以更轻松地自由地按照行自动分组。 我还没有testing这个绑定,但看到我跟踪$索引我不认为这应该是一个问题。

很想听到反馈。

我创build了一个名为“splitrow”的filter,它接受一个参数(每行中有多less项)

 .filter('splitrow', function(){ return function (input, count){ var out = []; if(typeof input === "object"){ for (var i=0, j=input.length; i < j; i+=count) { out.push(input.slice(i, i+count)); } } return out; } }); 

在视图模板中,我组织了引导行,如下所示:

 <div ng-init="rows = (items|splitrow:3)"> <div ng-repeat='row in rows' class="row"> <div ng-repeat="item in row track by $index" class="col-md-4"> {{item.property}} </div> </div> </div> 

我编辑@ Shivam的Plunker使用这种方法。 它不需要外部库。

Plunker

我的解决scheme与@CodeExpress非常相似。 我做了一个batchfilter,将数组的项目(该名称是从Twig的对应filter中借用的 )进行分组。 为了简单起见,我不处理关联数组。

 angular.module('myapp.filters', []) .filter('batch', function() { var cacheInputs = []; var cacheResults = []; return function(input, size) { var index = cacheInputs.indexOf(input); if (index !== -1) { return cacheResults[index]; } var result = []; for (i = 0; i < input.length; i += size) { result.push(input.slice(i, i + size)); } cacheInputs.push(input); cacheResults.push(result); return result; } }) ; 

它可以这样使用:

 <div ng-repeat="itemsRow in items|batch:3"> <div class="row"> <div ng-repeat="item in itemsRow"> <div class="col-md-4"> ... </div> </div> </div> </div> 

caching过滤结果以避免达到10 $digest() iterations reached. Aborting! 10 $digest() iterations reached. Aborting! 错误。

@ CodeExpress的纯angular度解决scheme的Angular2版本。

 alphabet: string[] = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; <div *ngIf='alphabet && alphabet.length'> <div *ngFor='#letter of alphabet; #i = index' > <div class="row" *ngIf='i % 4 == 0'> <div class="col-md-3" *ngFor='#n of [i,i+1,i+2,i+3]'> {{alphabet[n]}} </div> </div> </div> </div> 

这应该工作

 <div ng-repeat="item in items"> <div ng-class="{row : ($index % 3 == 0)}"> ... </div> </div>