Cách để lặp lại số lần xác định thay vì lặp lại trên mảng?


417

Có cách nào để ng-repeatxác định số lần thay vì luôn phải lặp lại trên một mảng không?

Ví dụ: bên dưới tôi muốn mục danh sách hiển thị 5 lần với giả sử $scope.numberbằng 5 ngoài ra tăng số lượng để mỗi mục danh sách tăng như 1, 2, 3, 4, 5

Kết quả như ý:

<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>


Bản sao lặp lại
TJ

Câu trả lời:


569

Cập nhật (25/9/2018)

Các phiên bản mới hơn của AngularJS (> = 1.3.0) cho phép bạn thực hiện việc này chỉ với một biến (không cần chức năng):

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

Điều này là không thể tại thời điểm câu hỏi đầu tiên được hỏi. Tín dụng cho @Nikhil Nambiar từ câu trả lời của anh ấy bên dưới cho bản cập nhật này


Bản gốc (29/5/2013)

Hiện tại, ng-repeatchỉ chấp nhận một bộ sưu tập làm tham số, nhưng bạn có thể làm điều này:

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

Và một nơi nào đó trong bộ điều khiển của bạn:

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

Điều này sẽ cho phép bạn thay đổi $scope.numberthành bất kỳ số nào bạn muốn và vẫn duy trì ràng buộc mà bạn đang tìm kiếm.

EDIT (1/6/2014) - Các phiên bản mới hơn của AngularJS (> = 1.1.5) yêu cầu track by $index:

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

Dưới đây là một câu đố với một vài danh sách sử dụng cùng getNumberchức năng.


Tôi đang sử dụng điều này cho nhiều mục danh sách nhưng dường như nó chỉ hoạt động cho danh sách đầu tiên. Bạn có biết tại sao lại như vậy không?
Malcr001

Nó sẽ làm việc cho bất kỳ số lượng danh sách. Kiểm tra câu đố này
Dan

1
Cảm ơn một lần nữa. Tôi quên xóa ng-repeat trên phần tử cha. Nó đang làm việc bây giờ. Cảm ơn.
Malcr001

3
$ scope.getNumber = function (num) {var x = new Array (); for (var i = 0; i <num; i ++) {x.push (i + 1); } trả về x; } // sử dụng chức năng này khi số thay đổi linh hoạt
Manavendher

1
@ sh0ber. Khi tôi cần thay đổi các mục danh sách dựa trên giá trị được chọn trong danh sách thả xuống số. Tôi đã thử chức năng của bạn trước, khi nó không hoạt động, tôi đã thay đổi nó thành ở trên để cập nhật không. của danh sách các mục khi số khác nhau được chọn trong danh sách thả xuống. Bạn có thể vui lòng kiểm tra kịch bản của tôi bằng cách sử dụng chức năng của bạn.
Manavendher

135

bạn có thể làm được việc này:

<div ng-repeat="i in [1, 2, 3, 4]">
  ...
</div>

1
hoạt động như một bùa mê, được thử nghiệm trên Chrome v. 39.0.2171.95 (64-bit), FF v. 33.1.1 và Safari v. 8.0.2
Neara 22/12/14

Điều này hoạt động hoàn hảo nếu bạn đang sử dụng nó trong điều khiển phân trang trong đó tất cả những gì bạn cần là <li> <a href = "javascript:;" ng-click = "SelectPage ($ index)"> {{i}} </a> </ li>
Rick

@AdityaMP, hãy sử dụng điều này cho các phạm vi trong javascript stackoverflow.com/a/31989462/3160597
azerafati 16/07/2016

1
Hãy xem xét việc gọi hàm tạo mảng cho một mảng có độ dài động, như đã nêu trong câu trả lời này .
maxathousand

Nếu tôi phải lặp lại 120 lần. Tôi có nên đi với [1,2,3 ... 120] không?
Munkhdelger Tumenbayar

94

Dưới đây là một ví dụ về cách bạn có thể làm điều này. Lưu ý rằng tôi đã được truyền cảm hứng bởi một nhận xét trong các tài liệu lặp lại: http://jsfiddle.net/digitalzebra/wnWY6/

Lưu ý chỉ thị ng-repeat:

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

Đây là bộ điều khiển:

function TestCtrl($scope) {
    $scope.range = function(n) {
        return new Array(n);
    };
};

8
Bạn cũng có thể sử dụng _.rangetừ Underscore hoặc lodash để tạo mảng: $ scope.range = _.range (0, n);
chiều

83

Tôi nghĩ rằng jsFiddle từ chủ đề này có thể là những gì bạn đang tìm kiếm.

<div ng-app ng-controller="Main">
   <div ng-repeat="item in items | limitTo:2">
       {{item.name}}
   </div>
</div>

3
đọc thêm về liên kết chủ đề google và nó mô tả cách bạn có thể sử dụng 'lát'. ví dụ: nhóm1: items.slice (0,3), nhóm2: items.slice (3,6), v.v.
trevorc

7
Câu trả lời này sẽ dẫn đến kết quả tối thiểu nhất trong bộ điều khiển của bạn và tôi tin rằng đó cũng là cách tiếp cận Angular ưa thích. IMO chấp nhận câu trả lời nên được thay thế bằng điều này.
Matt Jensen

1
Đây phải là câu trả lời được chấp nhận (theo ý kiến ​​của tôi) - Thanh lịch nhất, được ưa thích nhất.
Cody

11
@Cody Thật không may, không có nó không trả lời câu hỏi. OP tuyên bố "thay vì luôn phải lặp lại trên một mảng" và "giả sử $scope.numberbằng 5". Mục đích là sử dụng một biến số nguyên để xác định số lượng vật phẩm, không mã hóa nó và không sử dụng một mảng được xác định trước.
Dan

5
@Cody @ sh0ber bạn có thể đặt giới hạn trong phạm vi của mình ( $scope.limit = 2) và sử dụng nó như thế nào ...|limitTo:limit- xem fiddle cập nhật
drzaus

58

Một cách tiếp cận đơn giản hơn sẽ là (ví dụ 5 lần):

<div ng-repeat="x in [].constructor(5) track by $index">
       ...
</div>

5
Xuất sắc. Có thể đọc, ngắn và không có chức năng ngớ ngẩn trong bộ điều khiển để trả về một mảng mới.
maxathousand

2
Tôi yêu theo cách này.
Rabbi Shuki Gur

Được nâng cấp, điều này là không thể khi câu hỏi được hỏi lần đầu (Angular 1.2). Tôi đã sửa đổi câu trả lời được chấp nhận để bao gồm điều này. Công việc tốt!
Dan

1
Tôi chỉ muốn tôi hiểu tại sao cú pháp này hoạt động nhưng không Array(5)(hoặc thực sự [...Array(5).keys()]để có được một mảng [0,1,2,3,4])
Dylan Nicholson

50

Tôi gặp vấn đề tương tự. Tôi đã xem qua chủ đề này, nhưng không thích các phương pháp họ có ở đây. Giải pháp của tôi là sử dụng underscore.js mà chúng tôi đã cài đặt. Nó đơn giản như thế này:

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

Điều này sẽ làm chính xác những gì bạn đang tìm kiếm.


27
Điều này là tốt, nhưng lưu ý rằng Underscore không có trong phạm vi theo mặc định - bạn sẽ không thể sử dụng nó trong chế độ xem HTML của mình mà không làm điều gì đó như $scope._ = _.
jedd.ahyoung

6
Nếu bạn đang sử dụng lodash hoặc gạch dưới, bạn nên đặt nó vào $rootScopeđể nó có thể được sử dụng ở mọi nơi. Đặt app.runchức năng này vào chức năng của bạn ngay sau app.config: app.run(function ($rootScope) { $rootScope._ = _; });
Jeremy Moritz

Đây là một câu trả lời hoàn hảo cho tôi. Nó đơn giản và rất đơn giản. Vì tôi đang lặp lại bằng cách sử dụng một biến có số đếm, tôi phải thực hiện ng-repeat = "n trong _.range (1, đếm + 1). Cảm ơn về giải pháp.
Darryl

Tôi đã thử điều này và trong khi _ xuất hiện trong $ rootScope, ng-repeat không hiển thị bất cứ thứ gì.
Paul

49

Tôi muốn giữ cho html của mình rất tối thiểu, vì vậy đã xác định một bộ lọc nhỏ tạo ra mảng [0,1,2, ...] như những người khác đã làm:

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

Sau đó, trên khung nhìn có thể sử dụng như thế này:

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

34

Đây thực sự là UGLY, nhưng nó hoạt động mà không có bộ điều khiển cho số nguyên hoặc biến:

số nguyên:

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

Biến đổi:

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

Hack tốt nhất bao giờ hết! Cảm ơn
jannis

2
_ in (_ = []).length = 33; _ track by $indexnhỏ hơn một chút
Fabricio

16

Có rất nhiều cách để làm điều này. Tôi thực sự bận tâm khi có logic trong bộ điều khiển của mình vì vậy tôi đã tạo ra một lệnh đơn giản để giải quyết vấn đề lặp lại một phần tử n lần.

Cài đặt:

Lệnh có thể được cài đặt bằng bower install angular-repeat-n

Thí dụ:

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

sản xuất: 1234

Nó cũng hoạt động bằng cách sử dụng một biến phạm vi:

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

Nguồn:

Github


1
Đây là điều họ nên xem xét thêm vào các chỉ thị góc chính thức
HarshaXsoad

13

Đây chỉ là một biến thể nhỏ trong câu trả lời được chấp nhận, nhưng bạn không thực sự cần phải tạo một chức năng mới . Chỉ để nhập 'Mảng' trong phạm vi:

<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;
});

Xem fiddle này cho một ví dụ trực tiếp.


4
cập nhật (2016) và sạch sẽ hơn nhiều!
Julien Malige

9

Câu trả lời dễ nhất: 2 dòng mã

JS (trong bộ điều khiển AngularJS của bạn)

$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>

... Đâu repeatCountlà số lần lặp lại sẽ xuất hiện ở vị trí này.


1
Tôi tin rằng điều này không cho phép bạn thay đổi số lần lặp lại trong HTML nếu nó được thay đổi trong bộ điều khiển, trừ khi bạn bọc nó trong một chức năng như các câu trả lời khác đã làm.
phân ly

@trysis: Tôi không chắc là tôi có hiểu vấn đề của bạn không, nhưng bạn nên thay thế repeatCountbằng một số thực trong HTML và miễn là số đó nhỏ hơn hoặc bằng MAX_REPEATS, điều này sẽ cho phép bạn đặt số lặp lại trong HTML.
JellicleCat

1
Theo tôi, đây là cách thanh lịch nhất để hạn chế ngRepeatchỉ thị. Sử dụng Array.prototype.slicevà thành ngữ JS phải luôn luôn được chọn trên một thư viện như underscore.js (tùy thuộc vào trình duyệt).
Pat Migliaccio

Không phải là một giải pháp tồi, +1, nhưng tôi nghĩ câu trả lời này dễ hơn và tránh làm lộn xộn bộ điều khiển.
maxathousand

8

angular cho một chức năng rất ngọt gọi là lát .. sử dụng cái này bạn có thể đạt được những gì bạn đang tìm kiếm. ví dụ: ng-repeat = "ab in abc.slice (start Index, end Index)"

bản demo này: http://jsfiddle.net/sahilosheal/LurcV/39/ sẽ giúp bạn ra ngoài và cho bạn biết cách sử dụng chức năng "làm cho cuộc sống dễ dàng" này. :)

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'}];
    }

6

Đây là một câu trả lời cho góc 1.2.x

Về cơ bản là như vậy, với sự sửa đổi nhỏ của ng-repeat

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

đây là câu đố: http://jsfiddle.net/cHQLH/153/

điều này là do góc 1,2 không cho phép các giá trị trùng lặp trong lệnh. Điều này có nghĩa là nếu bạn đang cố gắng làm như sau, bạn sẽ gặp lỗi.

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

6

Bạn có thể sử dụng ng-ifchỉ thị vớing-repeat

Vì vậy, nếu num là số lần bạn cần phần tử được lặp lại:

<li ng-repeat="item in list" ng-if="$index < num">

1
Đối với những người bạn thích đánh dấu sạch ... Hãy nhớ sử dụng ng-repeattheo cách này vẫn sẽ xuất ra các thẻ nhận xét ( <!-- ngIf: $index < num -->vv ..). Đơn giản là sẽ không có bất kỳ liyếu tố nào để DOM hiển thị. Kiểm tra "nguồn xem" trên khung kết quả ở đây để xem ý tôi là gì.

3

Bạn có thể sử dụng ví dụ này.

Bộ điều khiển bên trong:

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

Ví dụ cho phần tử được chọn ở phía mã 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>

3

Đối với người dùng sử dụng CoffeeScript, bạn có thể sử dụng phạm vi hiểu:

Chỉ thị

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

hoặc Bộ điều khiển

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

Bản mẫu

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

3

Mở rộng một chút về câu trả lời đầu tiên của Ivan một chút, bạn có thể sử dụng một chuỗi làm bộ sưu tập mà không cần theo dõi bằng câu lệnh miễn là các ký tự là duy nhất, vì vậy nếu trường hợp sử dụng ít hơn 10 số như câu hỏi tôi chỉ cần làm :

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

Đó là một chút jenky, chắc chắn, nhưng đủ đơn giản để xem xét và không đặc biệt khó hiểu.


2

Đầu tiên, tạo bộ lọc góc bằng LoDash:

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

Hàm thời gian LoDash có khả năng xử lý null, không xác định, 0, số và biểu diễn chuỗi số.

Sau đó, sử dụng nó trong HTML của bạn như sau:

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

hoặc là

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

1

Tôi cần một giải pháp năng động hơn cho vấn đề này - nơi tôi có thể tăng lặp lại.

HTML

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

Kiểm soát sao chép

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

Mã não

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

1

Angular cung cấp các bộ lọc để sửa đổi một bộ sưu tập. Trong trường hợp này, bộ sưu tập sẽ là null, tức là [] và bộ lọc cũng lấy các đối số, như sau:

<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;
}]);

Phương pháp này rất giống với các phương pháp được đề xuất ở trên và không nhất thiết phải vượt trội nhưng cho thấy sức mạnh của các bộ lọc trong AngularJS.


1

Nếu n không quá cao, một tùy chọn khác có thể là sử dụng split ('') với một chuỗi n ký tự:

<div ng-controller="MainCtrl">
<div ng-repeat="a in 'abcdefgh'.split('')">{{$index}}</div>
</div>

Tôi tin rằng sự phân chia là không cần thiết ở đây. một chuỗi đã là một mảng các ký tự.
omike

1

Tôi đã gặp vấn đề tương tự và đây là những gì tôi đã đưa ra:

(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();
    }
  }
})();

... và html:

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

VÍ DỤ SỐNG

Tôi đã sử dụng timeschức năng gạch dưới như chúng tôi đã sử dụng nó trong dự án, nhưng bạn có thể dễ dàng thay thế nó bằng mã gốc.


0

Tôi đang tạo một chỉ thị có thể sử dụng lại trong đó số tối đa sẽ đến từ một lần lặp lại khác. Vì vậy, đây là một chỉnh sửa trên câu trả lời bình chọn tốt nhất.

Chỉ cần thay đổi mã tại bộ điều khiển này -

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

Điều này sẽ trả về một mảng mới với số lần lặp được chỉ định


0

kể từ khi lặp qua một chuỗi, nó sẽ hiển thị một mục cho mỗi char:

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

chúng ta có thể sử dụng cách giải quyết xấu xí nhưng không có mã này bằng number|n decimal placesbộ lọc riêng.

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

bằng cách này, chúng ta sẽ có mynumbercác phần tử không có thêm mã. Nói '0.000'.
Chúng tôi sử dụng mynumber - 2để bù lại 0.
Nó sẽ không hoạt động cho các số dưới 3, nhưng có thể hữu ích trong một số trường hợp.


bạn đã sử dụng track by $index?
Biệt thự Ivan Ferrer

đây là ghetto af. nếu bạn sẽ bị buộc phải có một char cho mỗi lần lặp, bạn cũng có thể làm như vậyng-repeat="i in [1,2,3,4]"
Roi

tất nhiên, nhưng OP muốn số lần lặp là n lần dựa trên một biến$scope.number
Ivan Ferrer Villa

tại sao không 'abcd' thay vì 'aaaa' và sau đó loại bỏ theo dõi?
omike

aaaalà một ví dụ để giải thích cách giải quyết của tôi. Sử dụng mã hóa cứng 'aaaa' hoặc 'abcd', bạn sẽ có được một danh sách độ dài cố định, nhưng thêm mynumber-2số thập phân thành 0, bạn sẽ có được một 'chuỗi' với các mynumberký tự. Giả sử mynumber=5, bạn nhận được '0.000', sau đó chúng tôi lặp lại rằng sử dụng chỉ mục $
Ivan Ferrer Villa

0
$scope.number = 5;

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

-1

cách đơn giản:

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

trong thành phần / bộ điều khiển và sau đó:

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

Mã này là từ dự án bản thảo của tôi nhưng có thể được sắp xếp lại thành javascript thuần

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.