Ответ 1
Это больше проблема стиля или разметки, чем у AngularJS. Если вы действительно этого хотите, вы можете сделать:
<span ng:repeat="(index, value) in array">
{{value}}<br ng:show="(index+1)%3==0" />
</span>
Спасибо, что нашли время, чтобы прочитать это, мне было интересно, как я могу использовать ng-repeat, чтобы создать сетку, такую как box of options. Я бы хотел, чтобы массив повторял n-е число элементов, а затем переходил к следующей строке или столбцу, пока не будут перечислены все элементы. например.
Предполагая, что у меня есть массив вроде [opt1,opt2,opt3,opt4,opt5,opt6,opt7]
, я хотел бы отображать его следующим образом:
opt1 opt2 opt3
opt4 opt5 opt6
opt7
Это больше проблема стиля или разметки, чем у AngularJS. Если вы действительно этого хотите, вы можете сделать:
<span ng:repeat="(index, value) in array">
{{value}}<br ng:show="(index+1)%3==0" />
</span>
Извините за мои HAML и Bootstrap3:
.row
.col-lg-4
%div{'ng:repeat' => "item in array.slice(0, array.length / 3)"}
{{item}}
.col-lg-4
%div{'ng:repeat' => "item in array.slice(array.length / 3, array.length * 2/3)"}
{{item}}
.col-lg-4
%div{'ng:repeat' => "item in array.slice(array.length * 2/3, array.length)"}
{{item}}
Существует другая версия, с возможностью использования фильтров:
<div class="row">
<div class="col-md-4" ng-repeat="remainder in [0,1,2]">
<span ng-repeat="item in array" ng-if="$index % 3 == remainder">{{item}}</span>
</div>
</div>
Если все ваши элементы находятся в одном массиве, лучше всего сделать сетку в CSS. Эта статья должна быть полезной: http://css-tricks.com/dont-overthink-it-grids/
Вы можете использовать $index из ng-repeat, чтобы применить правильный класс для вашего столбца (в этом случае 4 столбца):
<div class="col-{{ $index % 4 }}"></div>
Если у вас есть 2-мерный массив (разделенный на строки и столбцы), который открывает больше возможностей, например, с использованием таблицы HTML.
Мне проще просто использовать ng-repeat в сочетании с ng-if и компенсировать любые индексы с помощью $index. Обратите внимание на нефрит ниже:
div(ng-repeat="product in products")
div.row(ng-if="$index % 2 === 0")
div.col(ng-init="p1 = products[$index]")
span p1.Title
div.col(ng-if="products.length > $index + 1", ng-init="p2 = products[$index + 1]")
span p2.Title
div.col(ng-if="products.length <= $index + 1")
Кажется, что логика в вашем JavaScript - лучший метод. Я бы просто укусил пулю и посмотрел:
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);
Затем вы можете создать angular filter
для этого:
Фильтр:
angular.module('lists', []).filter('matrical', function() {
return function(list, columns) {
return listToMatrix(list, columns);
};
});
Контроллер:
function listOfListsController($scope) {
$scope.lists = $http.get('/lists');
}
Вид:
<div class="row" ng-repeat="row in (lists | matrical:3)">
<div class="col col-33" ng-repeat="list in row">{{list.name}}</div>
</div>
С этим вы можете видеть, что вы получаете n
количество строк - каждый из которых содержит столбцы 3
. Когда вы меняете количество нужных столбцов, вы заметите, что количество строк изменяется соответствующим образом (при условии, что длина списка всегда одна и та же;)).
Здесь fiddle.
Обратите внимание, что вы получаете ol 'Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
. Это связано с тем, что angular вызывает функцию matrical
на каждой итерации. Предположительно, вы можете использовать псевдоним as results
, чтобы предотвратить angular от переоценки коллекции, но мне не повезло. Для этого лучше фильтровать сетку внутри вашего контроллера и использовать это значение для вашего ретранслятора: $filter('matrical')(items)
- , но, пожалуйста, отправьте сообщение, если вы встретите элегантный способ его фильтрации в ng-repeat
.
Я бы еще раз подчеркнул, что вы, вероятно, идете по темному переулку, пытаясь написать логику на ваш взгляд, но я рекомендую вам попробовать ее, если вы этого еще не сделали.
Использование этого алгоритма должно сочетаться с Matrical Data-Structure, чтобы предоставить методы push
, pop
, splice
, а дополнительные методы - в сочетании с соответствующей логикой для дополнения Двунаправленного привязки данных, если это необходимо. Другими словами, привязка данных не будет работать из коробки (конечно), как при добавлении нового элемента в ваш список, необходимо провести переоценку всего списка, чтобы сохранить структурную целостность матрицы.
Предложение: Используйте синтаксис $filter('matrical')($scope.list)
в сочетании с $scope.$watch
и перекомпилируйте/вычислите позиции позиции для матрицы.
Ура!