-->

Way to ng-repeat defined number of times instead o

2018-12-31 15:46发布

问题:

Is there a way to ng-repeat a defined number of times instead of always having to iterate over an array?

For example, below I want the list item to show up 5 times assuming $scope.number equal to 5 in addition incrementing the number so each list item increments like 1, 2, 3, 4, 5

Desired result:

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

回答1:

At the moment, ng-repeat only accepts a collection as a parameter, but you could do this:

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

And somewhere in your controller:

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

This would allow you to change $scope.number to any number as you please and still maintain the binding you\'re looking for.

Here is a fiddle with a couple of lists using the same getNumber function.

EDIT 1/6/2014: Newer versions of Angular 1.x make use of the following syntax:

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

EDIT 9/25/2018: Newer versions of Angular 1.x allow you to do this without a function. If your code is simple and you don\'t need a getNumber function for other reasons, you can now omit that and just do this:

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

Credit to @Nikhil Nambiar from his answer below for this update



回答2:

you can do this:

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


回答3:

Here is an example of how you could do this. Note that I was inspired by a comment in the ng-repeat docs: http://jsfiddle.net/digitalzebra/wnWY6/

Note the ng-repeat directive:

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

Here is the controller:

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


回答4:

I think this jsFiddle from this thread might be what you\'re looking for.

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


回答5:

I ran into the same issue. I came across this thread, but didn\'t like the methods they had here. My solution was using underscore.js, which we had already installed. It\'s as simple as this:

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

This will do exactly what you\'re looking for.



回答6:

I wanted to keep my html very minimal, so defined a small filter that creates the array [0,1,2,...] as others have done:

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

After that, on the view is possible to use like this:

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


回答7:

A simpler approach would be (for an example of 5 times):

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


回答8:

This is really UGLY, but it works without a controller for either an integer or variable:

integer:

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

variable:

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


回答9:

There are many ways to do this. I was really bothered at having the logic in my controller so I created a simple directive to solve the problem of repeating an element n-times.

Installation:

The directive can be installed using bower install angular-repeat-n

Example:

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

produces: 1234

It also works using a scope variable:

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

Source:

Github



回答10:

This is only a slight variation on the accepted answer, but you don\'t really need to create a new function. Only to import \'Array\' in the scope:

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

See this fiddle for a live example.



回答11:

Easiest answer: 2 lines of code

JS (in your AngularJS controller)

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

...where repeatCount is the number of repetitions that should appear in this location.



回答12:

angular gives a very sweet function called slice.. using this you can achieve what you are looking for. e.g. ng-repeat=\"ab in abc.slice(startIndex,endIndex)\"

this demo :http://jsfiddle.net/sahilosheal/LurcV/39/ will help you out and tell you how to use this \"making life easy\" function. :)

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


回答13:

Heres an answer for angular 1.2.x

Basically it is the same, with the slight modification of of the ng-repeat

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

here is the fiddle: http://jsfiddle.net/cHQLH/153/

this is because angular 1.2 doesn\'t allow duplicate values in the directive. This means if you are trying to do the following, you will get an error.

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


回答14:

You can use the ng-if directive with ng-repeat

So, if num is the number of times you need the element repeated:

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


回答15:

For users using CoffeeScript, you can use a range comprehension:

Directive

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

or Controller

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

Template

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


回答16:

First, create an angular filter using LoDash:

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

The LoDash times function is capable of handling null, undefined, 0, numbers, and string representation of numbers.

Then, use it in your HTML as this:

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

or

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


回答17:

You can use this example.

Inside controller:

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

Example for select element at the HTML code side:

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


回答18:

Expanding a bit on Ivan\'s first answer a bit, you can use a string as the collection without a track by statement so long as the characters are unique, so if the use-case is less than 10 numbers as is the question I would simply do:

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

Which is a bit jenky, sure, but simple enough to look at and not particularly confusing.



回答19:

If n is not too high, another option could be to use split(\'\') with a string of n characters :

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


回答20:

I encountered the same problem and this is what I came out with:

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

... and the html:

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

LIVE EXAMPLE

I used underscore\'s times function as we where already using it on the project, but you can easily replace that with native code.



回答21:

I needed a more dynamic solution to this - where I could increment the repeat.

HTML

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

Duplicator Control

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


回答22:

Angular provides filters to modify a collection. In this case the collection would be null, i.e. [], and the filter also takes arguments, as follows:

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

This method is very similar to those proposed above and isn\'t necessarily superior but shows the power of filters in AngularJS.



回答23:

I am creating a reusable directive where the max number will come from another ng-repeat. So, this is an edit over the best voted answer.

Just change the code at controller to this -

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

This will return a new array with specified number of iterations



回答24:

since iterating over a string it will render an item for each char:

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

we can use this ugly but no-code workaround using the number|n decimal places native filter.

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

this way we\'ll have mynumber elements with no extra code. Say \'0.000\'.
We use mynumber - 2 to compensate 0.
It won\'t work for numbers below 3, but might be useful in some cases.



回答25:

simple way:

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

in the component/controller and then:

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

This code is from my typescript project but could be rearranged to pure javascript