I have an existing HTML template that places tiles on the page using ngRepeat,
<div ng-repeat="product in productList">
<div class="product-tile">
Product content goes here...
</div>
</div>
The designer now needs to wrap every 3 tiles in an extra div.
Normally, I would loop through the list and either,
But I can't see how I would do either in Angular. Any suggestions as to how to handle this?
It is much better to "prime" the ViewModel so that it suits your View - it's called View-Model for a reason. So, your modified productList
could be:
$scope.productList =
[
[ {/* product */ }, { }, { } ],
[ { }, { }, { } ],
// etc...
];
And so, to iterate you would nest ng-repeat
s:
<div ng-repeat="row in productList">
<div ng-repeat="product in row" class="product-row-group">
<div class="product-tile">
</div>
</div>
</div>
But it is possible (although, inefficient) to "pseudo-step" through the array:
<div ng-repeat="product in productList">
<div ng-if="$index % 3 === 0"
ng-init="group = productList.slice($index, $index + 3)">
<div class="products-row">
<div class="product-tile" ng-repeat="grItem in group">
{{grItem}}
</div>
</div>
</div>
</div>
The first ng-repeat
goes over the entire array, but the inner ng-if
only renders every 3rd item and ng-init
creates a sub-array of 3 products aliased as group
. The inner ng-repeat
goes over the items in the group
of 3 products.
Demo
The only thing I can think to do is to partition the original productList
array once when you get it into an array of arrays, and then use nested ng-repeat
s to get the structure you are after.
The following demonstrates that approach:
angular.module('stackoverflow', []).controller('ProductListsCtrl', function($scope) {
$scope.productLists = partition([1, 2, 3, 4, 5, 6, 7, 8], 3);
});
/* You could put this in a utility library or something */
function partition(coll, size) {
var groups = [];
for (var groupIndex = 0, numGroups = Math.ceil(coll.length / size);
groupIndex < numGroups;
groupIndex++) {
var startIndex = groupIndex * size;
groups.push(coll.slice(startIndex, startIndex + size));
}
return groups;
}
.product-tile {
display: inline-block;
background-color: #9A9EDA;
height: 100px;
width: 100px;
line-height: 100px;
vertical-align: middle;
text-align: center;
margin-right: 10px;
}
.wrapper {
margin: 5px;
padding: 10px;
background-color: #634AFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="stackoverflow" ng-controller="ProductListsCtrl">
<div ng-repeat="productList in productLists" class="wrapper">
<div class="product-tile" ng-repeat="product in productList">
{{product}}
</div>
</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With