Pendekatan yang paling andal dan benar secara teknis adalah dengan mengubah data dalam pengontrol. Berikut adalah fungsi dan penggunaan potongan sederhana.
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);
Maka tampilan Anda akan terlihat seperti ini:
<div class="row" ng-repeat="rows in chunkedData">
<div class="span4" ng-repeat="item in rows">{{item}}</div>
</div>
Jika Anda memiliki masukan apa pun di dalam ng-repeat
, Anda mungkin ingin melepas / bergabung kembali dengan array saat data diubah atau saat dikirimkan. Berikut tampilannya dalam a $watch
, sehingga data selalu tersedia dalam format asli yang digabungkan:
$scope.$watch('chunkedData', function(val) {
$scope.data = [].concat.apply([], val);
}, true); // deep watch
Banyak orang lebih suka melakukannya dalam tampilan dengan filter. Ini dimungkinkan, tetapi sebaiknya hanya digunakan untuk tujuan tampilan! Jika Anda menambahkan masukan dalam tampilan yang difilter ini, ini akan menyebabkan masalah yang dapat diselesaikan, tetapi tidak cantik atau tidak dapat diandalkan .
Masalah dengan filter ini adalah ia mengembalikan larik bersarang baru setiap kali. Angular mengamati nilai balik dari filter. Pertama kali filter dijalankan, Angular mengetahui nilainya, lalu menjalankannya lagi untuk memastikan sudah selesai diubah. Jika kedua nilai sama, siklus diakhiri. Jika tidak, filter akan aktif berulang kali hingga sama, atau Angular menyadari digest loop tak terbatas sedang terjadi dan dimatikan. Karena array / objek bertingkat baru sebelumnya tidak dilacak oleh Angular, ia selalu melihat nilai yang dikembalikan berbeda dari sebelumnya. Untuk memperbaiki filter "tidak stabil" ini, Anda harus menggabungkan filter dalam sebuah memoize
fungsi. lodash
memiliki memoize
fungsi dan versi lodash terbaru juga menyertakan chunk
fungsi, jadi kita dapat membuat filter ini dengan sangat mudahnpm
modul dan menyusun skrip dengan browserify
atau webpack
.
Ingat: hanya tampilan! Saring di pengontrol jika Anda menggunakan input!
Pasang lodash:
npm install lodash-node
Buat filter:
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);
});
Dan inilah contoh dengan filter ini:
<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>
Pesan item secara vertikal
1 4
2 5
3 6
Mengenai kolom vertikal (daftar dari atas ke bawah) daripada horizontal (kiri ke kanan), implementasi yang tepat bergantung pada semantik yang diinginkan. Daftar yang terbagi secara tidak merata dapat didistribusikan dengan berbagai cara. Inilah salah satu caranya:
<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;
}
Namun, cara paling langsung dan sederhana untuk mendapatkan kolom adalah dengan menggunakan kolom CSS :
.columns {
columns: 3;
}
<div class="columns">
<div ng-repeat="item in ['a','b','c','d','e','f','g']">
{{item}}
</div>
</div>