Thanks for taking the time to read this, I was wondering how I might be able to use ng-repeat to create a grid like box of options. I would like to take an array repeat nth num
It seems putting the logic in your JavaScript is the best method. I would just bite-the-bullet and look into:
function listToMatrix(list, n) {
var grid = [], i = 0, x = list.length, col, row = -1;
for (var i = 0; i < x; i++) {
col = i % n;
if (col === 0) {
grid[++row] = [];
}
grid[row][col] = list[i];
}
return grid;
}
var matrix = listToMatrix(lists, 3);
console.log('#RedPill', matrix);
You can then create an angular filter
to handle this:
Filter:
angular.module('lists', []).filter('matrical', function() {
return function(list, columns) {
return listToMatrix(list, columns);
};
});
Controller:
function listOfListsController($scope) {
$scope.lists = $http.get('/lists');
}
View:
{{list.name}}
With this, you can see you get n
number of rows -- each containing "3
" columns. When you change the number of desired columns, you'll notice the number of rows changes accordingly (assuming the list-length is always the same ;)).
Here's a fiddle.
Note, that you get the ol' Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
. This is because Angular is recalling the matrical
function upon every iteration. Allegedly, you can use the as results
alias to prevent Angular from reevaluating the collection, but I had no luck. For this, it may be better to filter the grid inside of your controller and use that value for your repeater: $filter('matrical')(items)
-- but please post back if you come across an elegant way of filtering it in the ng-repeat
.
I would stress, again, you're probably heading down a dark alley by trying to write the logic in your view -- but I encourage you to try it in your view if you haven't already.
The use of this algorithm should be combined with a Matrical Data-Structure to provide methods of push
, pop
, splice
, and additional methods -- in tandem with appropriate logic to complement Bi-Directional Data-Binding if desired. In other words, data-binding will not work out of the box (of course) as when a new item is added to your list, a reevaluation of the entire list must take place to keep the matrix's structural integrity.
Suggestion: Use the $filter('matrical')($scope.list)
syntax in combination with $scope.$watch
and recompile/calculate item-positions for the matrix.
Cheers!