如何使用引导程序将 ng- 重复数据分割为三列

我使用 n- 重复与我的代码,我有’n’文本框的数量基于 n- 重复。我想用三列对齐文本框。

这是我的原则

<div class="control-group" ng-repeat="oneExt in configAddr.ext">
{{$index+1}}.
<input type="text" name="macAdr{{$index+1}}"
id="macAddress" ng-model="oneExt.newValue" value=""/>
</div>
165734 次浏览

The most reliable and technically correct approach is to transform the data in the controller. Here's a simple chunk function and usage.

function chunk(arr, size) {
var newArr = [];
for (var i=0; i<arr.length; i+=size) {
newArr.push(arr.slice(i, i+size));
}
return newArr;
}


$scope.chunkedData = chunk(myData, 3);

那么你的观点会是这样的:

<div class="row" ng-repeat="rows in chunkedData">
<div class="span4" ng-repeat="item in rows">\{\{item}}</div>
</div>

如果在 ng-repeat中有任何输入,您可能希望在修改数据或提交数据时解块/重新加入数组。下面是在 $watch中看起来的样子,这样数据总是以原始的、合并的格式存在:

$scope.$watch('chunkedData', function(val) {
$scope.data = [].concat.apply([], val);
}, true); // deep watch

许多人喜欢在视图中使用过滤器来实现这一点。这是可能的,但只能用于显示目的!如果在这个筛选视图中添加输入,将导致解决 can但是 不漂亮或不可靠的的问题。

这个过滤器的问题在于它每次都返回新的嵌套数组。Angular 正在观察滤波器的返回值。第一次运行过滤器时,Angular 知道该值,然后再次运行它,以确保它完成了更改。如果两个值相同,则循环结束。如果没有,过滤器将一次又一次地发射,直到它们是相同的,或者 Angular 意识到一个无限的消化循环正在发生并关闭。因为新的嵌套数组/对象之前没有被 Angular 跟踪,所以它总是看到返回值与之前的不同。要修复这些“不稳定”的过滤器,必须将过滤器包装在 memoize函数中。lodash有一个 memoize函数和最新版本的 loash 也包括一个 chunk函数,所以我们可以创建这个过滤器非常简单地使用 npm模块和编译的脚本与 browserifywebpack

Remember: display only! Filter in the controller if you're using inputs!

安装 loash:

npm install lodash-node

创建过滤器:

var chunk = require('lodash-node/modern/array/chunk');
var memoize = require('lodash-node/modern/function/memoize');


angular.module('myModule', [])
.filter('chunk', function() {
return memoize(chunk);
});

这里有一个过滤器的样本:

<div ng-repeat="row in ['a','b','c','d','e','f'] | chunk:3">
<div class="column" ng-repeat="item in row">
\{\{($parent.$index*row.length)+$index+1}}. \{\{item}}
</div>
</div>

垂直排列

1  4
2  5
3  6

对于垂直列(从上到下列出)而不是水平列(从左到右) ,确切的实现取决于所需的语义。分布不均匀的列表可以以不同的方式分布。这里有一个办法:

<div ng-repeat="row in columns">
<div class="column" ng-repeat="item in row">
\{\{item}}
</div>
</div>
var data = ['a','b','c','d','e','f','g'];
$scope.columns = columnize(data, 3);
function columnize(input, cols) {
var arr = [];
for(i = 0; i < input.length; i++) {
var colIdx = i % cols;
arr[colIdx] = arr[colIdx] || [];
arr[colIdx].push(input[i]);
}
return arr;
}

然而,获得列的最直接和最简单的方法是使用 < strong > CSS 列 :

.columns {
columns: 3;
}
<div class="columns">
<div ng-repeat="item in ['a','b','c','d','e','f','g']">
\{\{item}}
</div>
</div>

我有一个功能,并存储在一个服务,所以我可以使用它在我的应用程序:

服务范围:

app.service('SplitArrayService', function () {
return {
SplitArray: function (array, columns) {
if (array.length <= columns) {
return [array];
};


var rowsNum = Math.ceil(array.length / columns);


var rowsArray = new Array(rowsNum);


for (var i = 0; i < rowsNum; i++) {
var columnsArray = new Array(columns);
for (j = 0; j < columns; j++) {
var index = i * columns + j;


if (index < array.length) {
columnsArray[j] = array[index];
} else {
break;
}
}
rowsArray[i] = columnsArray;
}
return rowsArray;
}
}

});

总监:

$scope.rows   = SplitArrayService.SplitArray($scope.images, 3); //im splitting an array of images into 3 columns

标价:

 <div class="col-sm-12" ng-repeat="row in imageRows">
<div class="col-sm-4" ng-repeat="image in row">
<img class="img-responsive" ng-src="\{\{image.src}}">
</div>
</div>

基于 m59的非常好的答案。我发现,如果模型输入发生变化,它们就会变得模糊,所以一次只能改变一个字符。这是一个新的对象列表,适用于任何需要它的人:

更新为在一个页面上处理多个过滤器

app.filter('partition', function() {
var cache = {}; // holds old arrays for difference repeat scopes
var filter = function(newArr, size, scope) {
var i,
oldLength = 0,
newLength = 0,
arr = [],
id = scope.$id,
currentArr = cache[id];
if (!newArr) return;


if (currentArr) {
for (i = 0; i < currentArr.length; i++) {
oldLength += currentArr[i].length;
}
}
if (newArr.length == oldLength) {
return currentArr; // so we keep the old object and prevent rebuild (it blurs inputs)
} else {
for (i = 0; i < newArr.length; i += size) {
arr.push(newArr.slice(i, i + size));
}
cache[id] = arr;
return arr;
}
};
return filter;
});

And this would be the usage:

<div ng-repeat="row in items | partition:3:this">
<span class="span4">
\{\{ $index }}
</span>
</div>

M59的答案很不错。我不喜欢它的一点是,它使用 div作为表的潜在数据。

因此,结合 m59的过滤器(答案在上面的某个地方) ,下面是如何在表中显示它。

<table>
<tr class="" ng-repeat="rows in foos | chunk:2">
<td ng-repeat="item in rows">\{\{item}}</td>
</tr>
</table>

一个干净,适应性强的解决方案,不需要数据操作:

HTML:

<div class="control-group" class="label"
ng-repeat="oneExt in configAddr.ext"
ng-class="{'new-row': startNewRow($index, columnBreak) }">
\{\{$index+1}}.
<input type="text" name="macAdr\{\{$index+1}}"
id="macAddress\{\{$index}}" ng-model="oneExt.newValue" />
</div>

CSS:

.label {
float: left;
text-align: left;
}
.new-row {
clear: left;
}

JavaScript:

$scope.columnBreak = 3; //Max number of colunms
$scope.startNewRow = function (index, count) {
return ((index) % count) === 0;
};

这是一个动态地将数据呈现为行和列的简单解决方案,不需要操作要显示的数据数组。另外,如果您尝试调整浏览器窗口的大小,您可以看到网格动态适应屏幕/div 的大小。

(我还在 id 中添加了一个\{\{ $index }}}后缀,因为如果您不这样做,ng-repeat 将尝试创建具有相同 id 的多个元素。)

A similar working example

下面是一个更简单的方法:

<table>
<tr ng-repeat="item in lists" ng-hide="$index%2!==0">
<td>
<label>\{\{ lists[$index].name}}</label>
</td>
<td ng-hide="!lists[$index+1]">
<label>\{\{ lists[$index+1].name}}</label>
</td>
</tr>
</table>

Cumulo Nimbus 的答案对我来说很有用,但是我希望这个网格被一个 div 包装起来,当列表太长时,这个 div 可以显示滚动条。

To achieve this I added style="height:200px; overflow:auto" to a div around the table which causes it to show as a single column.

现在数组长度为1。

I'm new in bootstrap and angularjs, but this could also make Array per 4 items as one group, the result will almost like 3 columns. 此技巧采用自举断线原理。

<div class="row">
<div class="col-sm-4" data-ng-repeat="item in items">
<div class="some-special-class">
\{\{item.XX}}
</div>
</div>
</div>

另一种方法是将 width:33.33%; float:left设置为包装器 div,如下所示:

<div ng-repeat="right in rights" style="width: 33.33%;float: left;">
<span style="width:60px;display:inline-block;text-align:right">\{\{$index}}</span>
<input type="number" style="width:50px;display:inline-block" ">
</div>

我的方法是多种多样的。

My objective was to have a grid adapting to the screen size. I wanted 3 columns for lg, 2 columns for sm and md, and 1 column for xs.

首先,我使用角度 $window服务创建了以下作用域函数:

$scope.findColNumberPerRow = function() {
var nCols;
var width = $window.innerWidth;


if (width < 768) {
// xs
nCols = 1;
}
else if(width >= 768 && width < 1200) {
// sm and md
nCols = 2
} else if (width >= 1200) {
// lg
nCols = 3;
}
return nCols;
};

然后,我使用了@Cumulo Nimbus 提出的类:

.new-row {
clear: left;
}

在包含 ng-repeat的 div 中,我添加了 resizable指令,如 这一页中所解释的那样,这样每次窗口调整大小时,角 $window服务就会用新值更新。

最后,在重复的 div 中,我得到:

ng-repeat="user in users" ng-class="{'new-row': ($index % findColNumberPerRow() === 0) }"

请告诉我这个方法的缺陷。

Hope it can be helpful.

Lodash 内置了一个我个人使用的块方法: https://lodash.com/docs#chunk

基于此,控制器代码可能如下所示:

$scope.groupedUsers = _.chunk( $scope.users, 3 )

查看代码:

<div class="row" ng-repeat="rows in groupedUsers">
<div class="span4" ng-repeat="item in rows">\{\{item}}</div>
</div>

此示例生成一个嵌套中继器,其中外部数据包括一个内部数组,我想在两列中列出这个内部数组。这个概念适用于三个或三个以上的栏目。

在内栏中,我重复“行”,直到达到极限。限制是通过项数组的长度除以所需的列数来确定的,在本例中是除以2。除法方法位于控制器上,并将当前数组长度作为参数传递。然后,JavaScript 片(0,array.length/columnCount)函数将限制应用于中继器。

然后调用第二列中继器并重复切片(array.length/columnCount,array.length) ,这将生成第二列中数组的后半部分。

<div class="row" ng-repeat="GroupAccess in UsersController.SelectedUser.Access" ng-class="{even: $even, odd: $odd}">
<div class="col-md-12 col-xs-12" style=" padding-left:15px;">
<label style="margin-bottom:2px;"><input type="checkbox" ng-model="GroupAccess.isset" />\{\{GroupAccess.groupname}}</label>
</div>
<div class="row" style=" padding-left:15px;">
<div class="col-md-1 col-xs-0"></div>
<div class="col-md-3 col-xs-2">
<div style="line-height:11px; margin-left:2px; margin-bottom:2px;" ng-repeat="Feature in GroupAccess.features.slice(0, state.DivideBy2(GroupAccess.features.length))">
<span class="GrpFeature">\{\{Feature.featurename}}</span>
</div>
</div>
<div class="col-md-3 col-xs-2">
<div style="line-height:11px; margin-left:2px; margin-bottom:2px;" ng-repeat="Feature in GroupAccess.features.slice( state.DivideBy2(GroupAccess.features.length), GroupAccess.features.length )">
<span class="GrpFeature">\{\{Feature.featurename}}</span>
</div>
</div>
<div class="col-md-5 col-xs-8">
</div>
</div>
</div>




// called to format two columns
state.DivideBy2 = function(nValue) {
return Math.ceil(nValue /2);
};

希望这能帮助我们从另一个角度来看待这个问题。(附注: 这是我在这里的第一个帖子!:-))

我修理没有。行

<div class="col col-33 left" ng-repeat="photo in photos">
Content here...
</div>

还有 CSS

.left {
float: left;
}

这个解决方案非常简单:

杰森:

[{id:"1",name:"testA"},{id:"2",name:"test B"},{id:"3",name:"test C"},{id:"4",name:"test D"},{id:"5",name:"test E"}]

HTML:

<div ng-controller="MyCtrl">
<table>
<tr ng-repeat="item in items" ng-switch on="$index % 3">
<td ng-switch-when="0">
\{\{items[$index].id}} \{\{items[$index].name}}
</td>
<td ng-switch-when="0">
<span ng-show="items[$index+1]">
\{\{items[$index+1].id}} \{\{items[$index+1].name}}
</span>
</td>
<td ng-switch-when="0">
<span ng-show="items[$index+2]">
\{\{items[$index+2].id}} \{\{items[$index+2].name}}
</span>
</td>
</tr>
</table>
</div>

小提琴演奏

enter image description here

这回答了最初的问题,即如何在列中得到1,2,3。Kuppu 在8’14年2月8日13:47提问

Angularjs 代码:

function GetStaffForFloor(floor) {
var promiseGet = Directory_Service.getAllStaff(floor);
promiseGet.then(function (pl) {
$scope.staffList = chunk(pl.data, 3); //pl.data; //
},
function (errorOD) {
$log.error('Errored while getting staff list.', errorOD);
});
}
function chunk(array, columns) {
var numberOfRows = Math.ceil(array.length / columns);


//puts 1, 2, 3 into column
var newRow = []; //array is row-based.
for (var i = 0; i < array.length; i++) {
var columnData = new Array(columns);
if (i == numberOfRows) break;
for (j = 0; j < columns; j++)
{
columnData[j] = array[i + numberOfRows * j];
}
newRow.push(columnData);
}
return newRow;


////this works but 1, 2, 3 is in row
//var newRow = [];
//for (var i = 0; i < array.length; i += columns) {
//    newRow.push(array.slice(i, i + columns)); //push effectively does the pivot. array is row-based.
//}
//return newRow;
};

查看代码(注意: 使用引导程序3) :

<div class="staffContainer">
<div class="row" ng-repeat="staff in staffList">
<div class="col-md-4" ng-repeat="item in staff">\{\{item.FullName.length > 0 ? item.FullName + ": Rm " + item.RoomNumber : ""}}</div>
</div>
</div>
<div class="row">
<div class="col-md-4" ng-repeat="remainder in [0,1,2]">
<ul>
<li ng-repeat="item in items" ng-if="$index % 3 == remainder">\{\{item}}</li>
</ul>
</div>
</div>

这里有一个简单的方法。它更加人工化,并且以混乱的标记结束。我不建议这样做,但是在某些情况下这可能是有用的。

这里有一个小提琴环节 http://jsfiddle.net/m0nk3y/9wcbpydq/

HTML:

<div ng-controller="myController">
<div class="row">
<div class="col-sm-4">
<div class="well">
<div ng-repeat="person in people = data | limitTo:Math.ceil(data.length/3)">
\{\{ person.name }}
</div>
</div>
</div>
<div class="col-sm-4">
<div class="well">
<div ng-repeat="person in people = data | limitTo:Math.ceil(data.length/3):Math.ceil(data.length/3)">
\{\{ person.name }}
</div>
</div>
</div>
<div class="col-sm-4">
<div class="well">
<div ng-repeat="person in people = data | limitTo:Math.ceil(data.length/3):Math.ceil(data.length/3)*2">
\{\{ person.name }}
</div>
</div>
</div>
</div>
</div>

约翰逊:

var app = angular.module('myApp', []);


app.controller('myController', function($scope) {


$scope.Math = Math;
$scope.data = [
{"name":"Person A"},
...
];
});

这个设置要求我们在标记:/上使用一些 Math,所以您需要通过添加这一行来注入 Math: $scope.Math = Math;

所有这些答案似乎都过于工程化了。

到目前为止,最简单的方法是在 colmd-4列 bootstrap 中设置输入 div,然后 bootstrap 会根据 bootstrap 的12列特性将其自动格式化为3列:

<div class="col-md-12">
<div class="control-group" ng-repeat="oneExt in configAddr.ext">
<div class="col-md-4">
<input type="text" name="macAdr\{\{$index}}"
id="macAddress" ng-model="oneExt.newValue" value="" />
</div>
</div>
</div>

我发现自己处于类似的情况下,希望生成每个3列的显示组。但是,尽管我使用的是 bootstrap,我还是试图将这些组分成不同的父 div。我还想做一些通用的东西。

我用2个 ng-repeat接近它,如下所示:

<div ng-repeat="items in quotes" ng-if="!($index % 3)">
<div ng-repeat="quote in quotes" ng-if="$index <= $parent.$index + 2 && $index >= $parent.$index">
... some content ...
</div>
</div>

这使得更改到不同数量的列非常容易,并且可以分隔成多个父 div。

Bootstrap 推荐使用“ clearfix”CSS 的一个简单技巧:

<div class="row">
<div ng-repeat-start="value in values" class="col-md-4">
\{\{value}}
</div>
<div ng-repeat-end ng-if="$index % 3 == 0" class="clearfix"></div>
</div>

许多优点: 高效,快速,使用 Boostrap 推荐,避免可能的 $摘要问题,并且不改变角模型。

这段代码将帮助在 lg 和 md 模式下使用三列、 sm 模式下的两列和 xs 模式下的单列对元素进行对齐

<div class="row">
<div ng-repeat="oneExt in configAddr.ext">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4">
{$index+1}}.
<input type="text" name="macAdr\{\{$index+1}}"
id="macAddress" ng-model="oneExt.newValue" value=""/>
</div>
</div>

如果有人想要一个角7(和更高版本) ,这里是我在我的一个应用程序中使用的一个例子:

HTML:

                   <div class="container-fluid">
<div class="row" *ngFor="let reports of chunkData; index as i">
<div *ngFor="let report of reports" class="col-4 col-sm-4"
style="border-style:solid;background-color: antiquewhite">\{\{report}}</div>
</div>
</div>

。 TS 文件

export class ConfirmationPageComponent implements OnInit {
chunkData = [];
reportsArray = ["item 1", "item 2", "item 3", "item 4", "item 5", "item 6"];
  

constructor() {}


ngOnInit() {
this.chunkData = this.chunk(this.reportsArray, 3);
}


chunk(arr, size) {
var newArr = [];
for (var i = 0; i < arr.length; i += size) {
newArr.push(arr.slice(i, i + size));
}
return newArr;
}
}

这是一个非常棒的解决方案,可以根据从数据库中迭代的项数动态创建新的列/行。谢谢!