Reputation: 10812
My angular is 1.0.8-stable
My objective is to display data in rows of 3.
My html should look like
<div class="table-row">
<div class="item">item1</div>
<div class="item">item2</div>
<div class="item">item3</div>
</div>
My pseudo code is if the $index mod 3 == 0 then I will display <div class="table-row">
.
if the $index mod 3 == 2, then I will display </div>
.
So far, I have this.
<div ng-repeat='item in my_works.items'>
<!-- if index mod 3 == 0 show <div>-->
<!-- if index mod 3 == 2 show </div>-->
</div>
Perhaps I was thinking it in the wrong way as there may be a more efficient way to do this in angularjs?
Upvotes: 2
Views: 3930
Reputation: 24676
Since you can't use ng-if
in 1.0.8 here are two variations that solve the problem. They both wrap 3 items into a table-row div
The outer loop counts off in groups of three, so it fires once per outer table-row div
. The second approach uses a filter to control the loop range but it should have better performance. The first approach doesn't require a new filter.
Then the inner ng-repeat
loops through the 3 items within a row. It uses slice to get just the 3 array items needed for that particular row.
Here's a fiddle with both of the variations working: http://jsfiddle.net/f8D8q/4/
Option 1: Solution without a new filter:
<div ng-repeat='itemtmp in items|limitTo:(items.length/3)+1'>
<div class="table-row">
<span ng-repeat='item in items.slice($index*3,($index*3+3))'>
{{item.name}} - {{$index}}
</span>
</div>
</div>
Option 2: More performant solution using range filter from http://www.yearofmoo.com/2012/10/more-angularjs-magic-to-supercharge-your-webapp.html#more-about-loops
<div ng-repeat="n in [] | range:(items.length/3)+1">
<div class="table-row">
<span ng-repeat='item in items.slice($index*3,($index*3+3))'>
{{item.name}} - {{$index}}
</span>
</div>
</div>
and the associated range filter:
app.filter('range', function () {
return function (input, total) {
total = parseInt(total);
for (var i = 0; i < total; i++) {
input.push(i);
}
return input;
};
});
Both are tested (down to 1.0.2) and work.
Upvotes: 2
Reputation: 1044
<div class="table-row" ng-repeat="list in listOfLists"> <div class="item" ng-repeat="item in list"> {{ item }} </div> </div>
If you already have a list, items
, you could add a filter chunked
and replace listOfLists
with items|chunked:3
, assuming you implement chunked
something like this:
app.filter('chunked', function(){
return function(list, chunkSize){
var chunks = [];
angular.forEach(list, function(element, i){
if(i % chunkSize === 0){
currentChunk = [];
chunks.push(currentChunk);
}
currentChunk.push(element);
});
return chunks;
};
});
I think that matches what you are trying to do; here's a plunker: http://plnkr.co/edit/3h7JprbXFVwnNZErj7hl
I didn't get a chance to test with old Angular though.
Upvotes: 1
Reputation: 133403
You can use (key, value) in expression
– where key and value can be any user defined identifiers, and expression is the scope expression giving the collection to enumerate.
You can try something like this
<div ng-repeat='(index, item) in my_works.items'>
<div class="table-row" ng-show="index % 3 == 0">
</div>
</div>
Upvotes: 3