感谢您花时间阅读本文,我想知道如何使用 ng-repeat 创建一个类似于选项框的网格。我想取一个数组重复第 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/
您可以使用 ng-repeat 中的 $index 为您的列应用正确的类(在本例中为 4 列网格):
<div class="col-{{ $index % 4 }}"></div>
如果你有一个二维数组(分成行和列),它会打开更多的可能性,比如实际使用 HTML 表。
I find it easier to simply use ng-repeat combined with ng-if and offsetting any indexes using $index. Mind the jade below:
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);
然后,您可以创建一个角度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
”列。当您更改所需的列数时,您会注意到行数会相应更改(假设列表长度始终相同;))。
这是一个小提琴。
请注意,您会得到 ol' Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
。这是因为 Angularmatrical
在每次迭代时都会调用该函数。据称,您可以使用as results
别名来阻止 Angular 重新评估集合,但我没有运气。为此,最好在控制器内部过滤网格并将该值用于中继器:$filter('matrical')(items)
-但如果您在ng-repeat
.
我要再次强调,您可能会尝试在您的视图中编写逻辑,从而走上一条黑暗的小巷——但如果您还没有尝试过,我鼓励您在您的视图中尝试它。
该算法的使用应与矩阵数据结构相结合,以提供push
、pop
、splice
和其他方法 - 如果需要,与适当的逻辑一起补充双向数据绑定。换句话说,数据绑定不会开箱即用(当然),因为当将新项目添加到列表中时,必须重新评估整个列表以保持矩阵的结构完整性。
建议:结合使用$filter('matrical')($scope.list)
语法$scope.$watch
并重新编译/计算矩阵的项目位置。
干杯!