Cara untuk ng-ulangi berapa kali didefinisikan daripada mengulangi lebih dari array?

417

Apakah ada cara untuk ng-repeatmenentukan berapa kali alih-alih selalu harus beralih ke array?

Sebagai contoh, di bawah ini saya ingin item daftar muncul 5 kali dengan asumsi $scope.numbersama dengan 5 selain menambah nomor sehingga setiap item daftar bertambah seperti 1, 2, 3, 4, 5

Hasil yang diinginkan:

<ul>
   <li><span>1</span></li>
   <li><span>2</span></li>
   <li><span>3</span></li>
   <li><span>4</span></li>
   <li><span>5</span></li>
</ul>
Malcr001
sumber

Jawaban:

569

Pembaruan (25/9/2018)

Versi AngularJS yang lebih baru (> = 1.3.0) memungkinkan Anda melakukan ini hanya dengan variabel (tidak diperlukan fungsi):

<li ng-repeat="x in [].constructor(number) track by $index">
    <span>{{ $index+1 }}</span>
</li>
$scope.number = 5;

Ini tidak mungkin pada saat pertanyaan pertama kali diajukan. Penghargaan untuk @Nikhil Nambiar dari jawabannya di bawah untuk pembaruan ini


Asli (29/5/2013)

Saat ini, ng-repeathanya menerima koleksi sebagai parameter, tetapi Anda bisa melakukan ini:

<li ng-repeat="i in getNumber(number)">
    <span>{{ $index+1 }}</span>
</li>

Dan di suatu tempat di controller Anda:

$scope.number = 5;
$scope.getNumber = function(num) {
    return new Array(num);   
}

Ini akan memungkinkan Anda untuk mengubah $scope.numberke nomor apa pun sesuka Anda dan tetap mempertahankan ikatan yang Anda cari.

EDIT (1/6/2014) - Versi AngularJS yang lebih baru (> = 1.1.5) membutuhkan track by $index:

<li ng-repeat="i in getNumber(number) track by $index">
    <span>{{ $index+1 }}</span>
</li>

Berikut adalah biola dengan beberapa daftar menggunakan getNumberfungsi yang sama .

Dan
sumber
Saya menggunakan ini untuk beberapa item daftar tetapi sepertinya hanya berfungsi untuk daftar pertama. Apakah Anda tahu mengapa demikian?
Malcr001
Ini harus bekerja untuk sejumlah daftar. Lihat biola ini
Dan
1
Terima kasih lagi. Saya lupa menghapus ng-repeat pada elemen induk. Ini bekerja sekarang. Terima kasih.
Malcr001
3
$ scope.getNumber = function (num) {var x = new Array (); untuk (var i = 0; i <num; i ++) {x.push (i +1); } return x; } // gunakan fungsi ini ketika angka berubah secara dinamis
Manavendher
1
@ sh0ber. Ketika saya perlu mengubah item daftar berdasarkan nilai yang dipilih dalam dropdown angka. Saya mencoba fungsi Anda terlebih dahulu, ketika tidak berfungsi, saya mengubahnya ke atas untuk memperbarui no. dari daftar item ketika nomor yang berbeda dipilih di dropdown. Bisakah Anda memeriksa skenario saya menggunakan fungsi Anda.
Manavendher
135

kamu bisa melakukan ini:

<div ng-repeat="i in [1, 2, 3, 4]">
  ...
</div>
akonsu
sumber
1
bekerja seperti pesona, diuji pada Chrome v. 39.0.2171.95 (64-bit), FF v. 33.1.1 dan Safari v. 8.0.2
Neara
Ini berfungsi dengan baik jika Anda menggunakannya dalam kontrol pagination di mana yang Anda butuhkan adalah <li> <a href = "javascript:;" ng-klik = "SelectPage ($ index)"> {{i}} </a> </li>
Rick
@AdityaMP, gunakan ini untuk rentang di javascript stackoverflow.com/a/31989462/3160597
azerafati
1
Pertimbangkan memanggil konstruktor array untuk array panjang dinamis, seperti yang dinyatakan dalam jawaban ini .
maxathousand
bagaimana jika saya harus mengulangi 120 kali. Haruskah saya menggunakan [1,2,3 ... 120]?
Munkhdelger Tumenbayar
94

Berikut adalah contoh bagaimana Anda bisa melakukan ini. Perhatikan bahwa saya terinspirasi oleh komentar di dokumen ng-repeat: http://jsfiddle.net/digitalzebra/wnWY6/

Perhatikan arahan ng-repeat:

<div ng-app>
    <div ng-controller="TestCtrl">
        <div ng-repeat="a in range(5) track by $index">{{$index + 1}}</div>
    </div>
</div>

Ini controllernya:

function TestCtrl($scope) {
    $scope.range = function(n) {
        return new Array(n);
    };
};
Polaris878
sumber
8
Anda juga dapat menggunakan _.rangedari Underscore atau lodash untuk membuat array: $ scope.range = _.range (0, n);
Sore
83

Saya pikir jsFiddle ini dari utas ini mungkin apa yang Anda cari.

<div ng-app ng-controller="Main">
   <div ng-repeat="item in items | limitTo:2">
       {{item.name}}
   </div>
</div>
jeffmayeur
sumber
3
baca lebih lanjut di tautan google thread dan itu menjelaskan bagaimana Anda dapat menggunakan 'slice'. mis. group1: items.slice (0,3), group2: items.slice (3,6), dll.
trevorc
7
Jawaban ini akan menghasilkan jejak kaki yang paling minimal di controller Anda dan saya percaya adalah pendekatan Angular yang disukai juga. Jawaban yang diterima IMO harus diganti dengan ini.
Matt Jensen
1
Ini harus menjadi jawaban yang diterima (menurut saya) - Paling elegan, paling disukai.
Cody
11
@Cody Sayangnya, tidak, itu tidak menjawab pertanyaan. OP menyatakan "alih-alih selalu harus beralih pada array" dan "dengan asumsi $scope.numbersama dengan 5". Maksudnya adalah untuk menggunakan variabel integer untuk menentukan jumlah item, bukan hardcode dan tidak menggunakan array yang telah ditentukan.
Dan
5
@Cody @ sh0ber Anda dapat mengatur batas dalam lingkup Anda ( $scope.limit = 2) dan menggunakannya seperti ...|limitTo:limit- lihat biola diperbarui
drzaus
58

Pendekatan yang lebih sederhana adalah (misalnya 5 kali):

<div ng-repeat="x in [].constructor(5) track by $index">
       ...
</div>
Nikhil Nambiar
sumber
5
Cemerlang. Dapat dibaca, pendek, dan tidak ada fungsi konyol di controller untuk mengembalikan array baru.
maxathousand
2
Saya suka cara ini.
Rabi Shuki Gur
Terpilih, ini tidak mungkin ketika pertanyaan pertama kali diajukan (Angular 1.2). Saya mengubah jawaban yang diterima untuk memasukkan ini. Pekerjaan yang baik!
Dan
1
Saya hanya berharap saya mengerti mengapa sintaks ini bekerja tetapi tidak Array(5)(atau memang [...Array(5).keys()]untuk mendapatkan array [0,1,2,3,4])
Dylan Nicholson
50

Saya mengalami masalah yang sama. Saya menemukan utas ini, tetapi tidak suka metode yang mereka miliki di sini. Solusi saya menggunakan underscore.js, yang sudah kami pasang. Sesederhana ini:

<ul>
    <li ng-repeat="n in _.range(1,6)"><span>{{n}}</span></li>
</ul>

Ini akan melakukan apa yang Anda cari.

Mark Roach
sumber
27
Ini bagus, tetapi perhatikan bahwa Garis Bawah tidak dalam ruang lingkup secara default - Anda tidak akan dapat menggunakannya dalam tampilan HTML Anda tanpa melakukan sesuatu seperti $scope._ = _.
jedd.ahyoung
6
Jika Anda menggunakan lodash atau garis bawah, Anda harus memasukkannya $rootScopesehingga dapat digunakan di mana-mana. Letakkan ini dalam app.runfungsi Anda tepat setelah app.config: app.run(function ($rootScope) { $rootScope._ = _; });
Jeremy Moritz
Ini jawaban yang sempurna bagi saya. Sederhana dan sangat mudah. Karena saya mengulangi menggunakan variabel yang memiliki hitungan, saya harus ng-repeat = "n in _.range (1, count + 1). Terima kasih untuk solusinya.
Darryl
Saya mencoba ini dan sementara _ muncul di $ rootScope, ng-repeat tidak membuat apa pun.
Paul
49

Saya ingin menjaga html saya sangat minimal, sehingga mendefinisikan filter kecil yang membuat array [0,1,2, ...] seperti yang dilakukan orang lain:

angular.module('awesomeApp')
  .filter('range', function(){
    return function(n) {
      var res = [];
      for (var i = 0; i < n; i++) {
        res.push(i);
      }
      return res;
    };
  });

Setelah itu, pada tampilan dimungkinkan untuk digunakan seperti ini:

<ul>
  <li ng-repeat="i in 5 | range">
    {{i+1}} <!-- the array will range from 0 to 4 -->
  </li>
</ul>
miguelr
sumber
34

Ini benar-benar UGLY, tetapi ia bekerja tanpa pengontrol untuk integer atau variabel:

bilangan bulat:

<span ng-repeat="_ in ((_ = []) && (_.length=33) && _) track by $index">{{$index}}</span>

variabel:

<span ng-repeat="_ in ((_ = []) && (_.length=myVar) && _) track by $index">{{$index}}</span>
MJ
sumber
Retas terbaik yang pernah ada! Terima kasih
jannis
2
_ in (_ = []).length = 33; _ track by $indexsedikit lebih kecil
Fabricio
16

Ada banyak cara untuk melakukan ini. Saya benar-benar terganggu karena memiliki logika di controller saya jadi saya membuat arahan sederhana untuk menyelesaikan masalah pengulangan elemen n-kali.

Instalasi:

Arahan dapat diinstal menggunakan bower install angular-repeat-n

Contoh:

<span ng-repeat-n="4">{{$index}}</span

menghasilkan: 1234

Ini juga berfungsi menggunakan variabel lingkup:

<span ng-repeat-n="repeatNum"></span>

Sumber:

Github

connorbode
sumber
1
Ini adalah sesuatu yang mereka harus pertimbangkan untuk menambah arahan sudut resmi
HarshaXsoad
13

Ini hanya sedikit variasi pada jawaban yang diterima, tetapi Anda tidak benar-benar perlu membuat fungsi baru . Hanya mengimpor 'Array' dalam cakupan:

<div ng-app="myapp">
    <div ng-controller="ctrlParent">
        <ul>
            <li ng-repeat="i in counter(5) track by $index">
              <span>{{$index+1}}</span></li>
        </ul>
    </div>
</div>
var app = angular.module('myapp',[]);
app.controller('ctrlParent',function($scope){
    $scope.myNumber = 5;
    $scope.counter = Array;
});

Lihat biola ini untuk contoh langsung.

Sylvain Leroux
sumber
4
terkini (2016) dan lebih bersih!
Julien Malige
9

Jawaban termudah: 2 baris kode

JS (di pengontrol AngularJS Anda)

$scope.range = new Array(MAX_REPEATS); // set MAX_REPEATS to the most repetitions you will ever need in a single ng-repeat that makes use of this strategy

HTML

<div ng-repeat="i in range.slice(0,repeatCount) track by $index"></div>

... di mana repeatCountjumlah pengulangan yang seharusnya muncul di lokasi ini.

JellicleCat
sumber
1
Saya percaya ini tidak memungkinkan Anda mengubah jumlah pengulangan dalam HTML jika diubah di controller, kecuali jika Anda membungkusnya dalam fungsi seperti jawaban lain yang telah dilakukan.
trysis
@trysis: Saya tidak yakin apakah saya memahami masalah Anda, tetapi Anda harus mengganti repeatCountdengan angka aktual dalam HTML, dan selama nomor itu kurang dari atau sama dengan MAX_REPEATS, ini akan memungkinkan Anda mengatur nomor pengulangan dalam HTML.
JellicleCat
1
Menurut pendapat saya, ini adalah cara paling elegan untuk membatasi ngRepeatarahan. Menggunakan Array.prototype.slicedan JS idiomatik harus selalu dipilih di atas pustaka seperti underscore.js (tergantung pada kompatibilitas browser).
Pat Migliaccio
Bukan solusi yang buruk, +1, tapi saya pikir jawaban ini lebih mudah, dan menghindari pengontrol yang berantakan.
maxathousand
8

angular memberikan fungsi yang sangat manis yang disebut slice .. menggunakan ini Anda dapat mencapai apa yang Anda cari. mis. ng-repeat = "ab in abc.slice (startIndex, endIndex)"

demo ini: http://jsfiddle.net/sahilosheal/LurcV/39/ akan membantu Anda dan memberi tahu Anda cara menggunakan fungsi "memudahkan hidup" ini. :)

html:

<div class="div" ng-app >
    <div ng-controller="Main">
        <h2>sliced list(conditional NG-repeat)</h2>
        <ul ng-controller="ctrlParent">
            <li ng-repeat="ab in abc.slice(2,5)"><span>{{$index+1}} :: {{ab.name}} </span></li>
        </ul>
        <h2>unsliced list( no conditional NG-repeat)</h2>
         <ul ng-controller="ctrlParent">
            <li ng-repeat="ab in abc"><span>{{$index+1}} :: {{ab.name}} </span></li>
        </ul>

    </div>

CSS:

ul
{
list-style: none;
}
.div{
    padding:25px;
}
li{
    background:#d4d4d4;
    color:#052349;
}

ng-JS:

 function ctrlParent ($scope) {
    $scope.abc = [
     { "name": "What we do", url: "/Home/AboutUs" },
     { "name": "Photo Gallery", url: "/home/gallery" },
     { "name": "What we work", url: "/Home/AboutUs" },
     { "name": "Photo play", url: "/home/gallery" },
     { "name": "Where", url: "/Home/AboutUs" },
     { "name": "playground", url: "/home/gallery" },
     { "name": "What we score", url: "/Home/AboutUs" },
     { "name": "awesome", url: "/home/gallery" },
     { "name": "oscar", url: "/Home/AboutUs" },
     { "name": "american hustle", url: "/home/gallery" }
    ];
}
function Main($scope){
    $scope.items = [{sort: 1, name: 'First'}, 
                    {sort: 2, name: 'Second'}, 
                    {sort: 3, name: 'Third'}, 
                    {sort: 4, name:'Last'}];
    }
sheelpriy
sumber
6

Inilah jawaban untuk 1.2.1 sudut

Pada dasarnya itu sama, dengan sedikit modifikasi dari ng-repeat

<li ng-repeat="i in getNumber(myNumber) track by $index">

di sini adalah biola: http://jsfiddle.net/cHQLH/153/

ini karena sudut 1.2 tidak memungkinkan nilai duplikat dalam arahan. Ini berarti jika Anda mencoba melakukan hal berikut, Anda akan mendapatkan kesalahan.

<li ng-repeat="x in [1,1,1]"></li>
DrogoNevets
sumber
6

Anda dapat menggunakan ng-ifarahan denganng-repeat

Jadi, jika num adalah berapa kali Anda perlu elemen diulang:

<li ng-repeat="item in list" ng-if="$index < num">
alias terima kasih
sumber
1
Bagi Anda yang suka membersihkan markup ... Perlu diingat menggunakan ng-repeatcara ini masih akan menampilkan tag komentar itu ( <!-- ngIf: $index < num -->dll ..). Tidak akan ada lielemen untuk DOM render. Periksa "sumber tampilan" pada panel hasil di sini untuk melihat apa yang saya maksud.
3

Anda dapat menggunakan contoh ini.

Pengontrol di dalam:

$scope.data = {
    'myVal': 33,
    'maxVal': 55,
    'indexCount': function(count) {
        var cnt = 10;
        if (typeof count === 'number') {
            cnt = count;
        }
        return new Array(cnt);
    }
};

Contoh untuk elemen pilih di sisi kode HTML:

<select ng-model="data.myVal" value="{{ data.myVal }}">
    <option ng-repeat="i in data.indexCount(data.maxVal) track by $index" value="{{ $index + 1 }}">{{ $index + 1 }}</option>
</select>
elceka
sumber
3

Untuk pengguna yang menggunakan CoffeeScript, Anda dapat menggunakan pemahaman rentang:

Pengarahan

link: (scope, element, attrs) ->
  scope.range = [1..+attrs.range]

atau Pengendali

$scope.range = [1..+$someVariable]
$scope.range = [1..5] # Or just an integer

Templat

<div ng-repeat="i in range">[ the rest of your code ]</div>
Roi
sumber
3

Memperluas sedikit jawaban pertama Ivan sedikit, Anda dapat menggunakan string sebagai koleksi tanpa trek dengan pernyataan selama karakternya unik, jadi jika case-use kurang dari 10 angka seperti pertanyaan saya hanya akan melakukan :

<ul>
   <li ng-repeat="n in '12345'"><span>{{n}}</span></li>
</ul>

Yang agak jenky, pasti, tapi cukup sederhana untuk dilihat dan tidak terlalu membingungkan.

omikes
sumber
2

Pertama, buat filter sudut menggunakan LoDash:

angular.module('myApp').filter('times', function(){
   return function(value){
      return _.times(value || 0);
   }
});

Fungsi kali LoDash mampu menangani angka null, tidak terdefinisi, 0, dan representasi string.

Kemudian, gunakan dalam HTML Anda karena ini:

<span ng-repeat="i in 5 | times">
 <!--DO STUFF-->
</span>

atau

<span ng-repeat="i in myVar | times">
 <!--DO STUFF-->
</span>
Karanvir Kang
sumber
1

Saya membutuhkan solusi yang lebih dinamis untuk ini - di mana saya bisa menambah pengulangan.

HTML

<div ng-repeat="n in newUserCount">
<input type="text" value="" name="newuser{{n}}"/>
</div>

Kontrol Duplikator

<span class="helper" ng-click="duplicateUser()">
Create another user with the same permissions
</span>

JS

 $scope.newUserCount = Array('1');
var primaryValue = 1;
$scope.duplicateUser = function()
{
    primaryValue++;
    $scope.newUserCount.push(primaryValue)
}
adswebwork
sumber
1

Angular menyediakan filter untuk mengubah koleksi. Dalam hal ini koleksi akan menjadi nol, yaitu [], dan filter juga menggunakan argumen, sebagai berikut:

<div id="demo">
    <ul>
        <li ng-repeat="not in []|fixedNumber:number track by $index">{{$index}}</li>
    </ul>
</div>

JS:

module.filter('fixedNumber', function() {
    return function(emptyarray, number) {
        return Array(number);
    }
});

module.controller('myCtrl', ['$scope', function($scope) {
    $scope.number = 5;
}]);

Metode ini sangat mirip dengan yang diusulkan di atas dan tidak selalu unggul tetapi menunjukkan kekuatan filter di AngularJS.

Nik Dow
sumber
1

Jika n tidak terlalu tinggi, opsi lain bisa menggunakan split ('') dengan string n karakter:

<div ng-controller="MainCtrl">
<div ng-repeat="a in 'abcdefgh'.split('')">{{$index}}</div>
</div>
vonwolf
sumber
Saya percaya perpecahan tidak perlu di sini. string sudah merupakan array karakter.
omikes
1

Saya mengalami masalah yang sama dan inilah yang saya hasilkan:

(function () {
  angular
    .module('app')
    .directive('repeatTimes', repeatTimes);

  function repeatTimes ($window, $compile) {
    return { link: link };

    function link (scope, element, attrs) {
      var times    = scope.$eval(attrs.repeatTimes),
          template = element.clone().removeAttr('repeat-times');

      $window._(times).times(function (i) {
        var _scope = angular.extend(scope.$new(), { '$index': i });
        var html = $compile(template.clone())(_scope);

        html.insertBefore(element);
      });

      element.remove();
    }
  }
})();

... dan html:

<div repeat-times="4">{{ $index }}</div>

CONTOH LANGSUNG

Saya menggunakan timesfungsi garis bawah seperti yang telah kita gunakan pada proyek, tetapi Anda dapat dengan mudah menggantinya dengan kode asli.

nicooga
sumber
0

Saya membuat arahan yang dapat digunakan kembali di mana nomor maks akan berasal dari ng-repeat lain. Jadi, ini adalah edit dari jawaban dengan suara terbaik.

Ubah saja kode di controller untuk ini -

$scope.getNumber = function(num) {
    var temp = [];
    for(var j = 0; j < num; j++){
        temp.push(j)
    }
    return temp; 
}

Ini akan mengembalikan array baru dengan jumlah iterasi yang ditentukan

sagars01
sumber
0

karena iterasi pada string, itu akan membuat item untuk setiap karakter:

<li ng-repeat = "k in 'aaaa' track by $index">
   {{$index}} //THIS DOESN'T ANSWER OP'S QUESTION. Read below.
</li>

kita bisa menggunakan solusi jelek tapi tanpa kode ini menggunakan number|n decimal placesfilter asli.

 <li ng-repeat="k in (0|number:mynumber -2 ) track by $index">
    {{$index}}
 </li>

dengan cara ini kita akan memiliki mynumberelemen tanpa kode tambahan. Katakan '0.000'.
Kami menggunakan mynumber - 2untuk mengkompensasi 0.
Ini tidak akan berfungsi untuk angka di bawah 3, tetapi mungkin berguna dalam beberapa kasus.

Ivan Ferrer Villa
sumber
yang Anda gunakan track by $index?
Ivan Ferrer Villa
ini adalah ghetto af. jika Anda akan dipaksa untuk memiliki arang untuk setiap iterasi yang mungkin Anda lakukanng-repeat="i in [1,2,3,4]"
Roi
tentu saja, tetapi OP ingin iterasi dilakukan berdasarkan variabel$scope.number
Ivan Ferrer Villa
mengapa tidak 'abcd' alih-alih 'aaaa' dan kemudian memo treknya?
Omikes
aaaaadalah contoh untuk menjelaskan solusi saya yang tidak terlalu elegan. Menggunakan hardcoded 'aaaa' atau 'abcd' Anda mendapatkan daftar panjang tetap, tetapi menambahkan mynumber-2desimal ke 0, Anda mendapatkan 'string' dengan mynumberkarakter. Katakanlah mynumber=5, Anda dapatkan '0.000', lalu kita beralih menggunakan $ index
Ivan Ferrer Villa
0
$scope.number = 5;

<div ng-repeat="n in [] | range:$scope.number">
      <span>{{$index}}</span>
</div>
DuFuS
sumber
-1

cara sederhana:

    public defaultCompetences: Array<number> = [1, 2, 3];

dalam komponen / controller dan kemudian:

    <div ng-repeat="i in $ctrl.defaultCompetences track by $index">

Kode ini dari proyek naskah saya tetapi bisa disusun ulang menjadi javascript murni

Pallepassion
sumber