ng重复定义次数而不是在数组上重复的方法?


417

有没有一种方法可以ng-repeat定义次数,而不必总是遍历数组?

例如,在下面,我希望列表项显示5次,并假设$scope.number等于5,并增加数字,因此每个列表项都按1、2、3、4、5递增

所需结果:

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


Answers:


569

更新(9/25/2018)

较新版本的AngularJS(> = 1.3.0)允许您仅使用变量(无需功能)来执行此操作:

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

在首次提出问题时这是不可能的。感谢@Nikhil Nambiar从下面的回答中获得此更新


原创(5/29/2013)

目前,ng-repeat仅接受集合作为参数,但是您可以这样做:

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

在控制器中的某个位置:

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

这样一来,您就可以随意更改$scope.number为任何数字,并且仍然保持您要查找的绑定。

编辑(1/6/2014) -较新版本的AngularJS(> = 1.1.5)需要track by $index

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

这是一个带有几个使用相同getNumber功能的列表的小提琴


我将其用于多个列表项,但它似乎仅适用于第一个列表。你知道为什么会这样吗?
Malcr001 2013年

它适用于任何数量的列表。检查这个小提琴

1
再次感谢。我忘了删除父元素上的ng-repeat。现在正在工作。谢谢。
Malcr001 2013年

3
$ scope.getNumber = function(num){var x = new Array(); for(var i = 0; i <num; i ++){x.push(i + 1); } return x; } //当数字动态变化时使用此函数
Manavendher

1
@ sh0ber。当我需要根据数字下拉列表中选择的值更改列表项时。我首先尝试了您的功能,当它不起作用时,我将其更改为上面的内容以更新编号。在下拉列表中选择其他编号时的列表项数量。您能使用您的功能检查我的情况吗?
Manavendher

135

你可以这样做:

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

1
工作就像一个魅力,在Chrome v测试39.0.2171.95(64位),FF v 33.1.1和Safari v 8.0.2。
Neara

如果您在分页控件中使用它,而您只需要<li> <a href =“ javascript :;” ng-click =“ SelectPage($ index)”> {{i}} </a> </ li>
Rick

@AdityaMP,将其用于javascript stackoverflow.com/a/31989462/3160597
azerafati 2016年

1
考虑如本答案所述,为动态长度数组调用数组构造函数。
maxathousand

如果我必须重复120次该怎么办。我应该选择[1,2,3 ... 120]吗?
Munkhdelger Tumenbayar

94

这是如何执行此操作的示例。请注意,我的灵感来自ng-repeat文档中的评论:http : //jsfiddle.net/digitalzebra/wnWY6/

注意ng-repeat指令:

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

这是控制器:

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

8
您还可以使用_.rangeUnderscore或lodash创建数组:$ scope.range = _.range(0,n);
2013年

83

我觉得这个的jsfiddle从这个线程可能是你在找什么。

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

3
进一步阅读Google线程链接,它描述了如何使用“切片”。例如,group1:items.slice(0,3),group2:item.slice(3,6)等
trevorc 2013年

7
这个答案将使您的控制器占用的空间最小化,我相信也是首选的Angular方法。IMO接受的答案应替换为此。
马特·詹森

1
这应该是公认的答案(在我看来)-最优雅,最受ng推荐。
科迪2014年

11
@Cody不幸的是,不,它不能回答问题。OP声明“而不是总是要遍历数组”和“假定$scope.number等于5”。目的是使用整数变量来定义项目计数,而不是对其进行硬编码并且不使用预定义的数组。
2014年

5
@Cody @ sh0ber,您可以在范围($scope.limit = 2)中设置限制,并像使用它一样使用它...|limitTo:limit-参见更新的提琴
drzaus 2014年

58

一个更简单的方法是(例如5次):

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

5
辉煌。控制器中的可读,简短且无傻功能的函数可以返回新数组。
maxathousand

2
我喜欢这种方式。
拉比Shuki古尔

赞成,当第一次提出问题时(角度1.2),这是不可能的。我修改了接受的答案以包括此内容。不错的工作!
丹丹

1
我只是希望我理解为什么此语法有效,但不能Array(5)(或者实际上不是[...Array(5).keys()]要获得数组[0,1,2,3,4])
Dylan Nicholson

50

我遇到了同样的问题。我遇到了这个线程,但是不喜欢他们在这里使用的方法。我的解决方案是使用我们已经安装的underscore.js。就这么简单:

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

这将完全满足您的需求。


27
很好,但是请注意,默认情况下,Underscore不在范围内-如果不执行,您将无法在HTML视图中使用它$scope._ = _
jedd.ahyoung 2014年

6
如果使用lodash或下划线,则应将其放入$rootScope以便可以在任何地方使用。将其放在app.run函数之后app.configapp.run(function ($rootScope) { $rootScope._ = _; });
杰里米·莫里茨

这对我来说是一个完美的答案。简单而直接。由于我使用的变量,它有一个计数重复,我不得不做NG-重复=“N在_.range(1,计数+ 1)感谢您的溶液。
达里尔

我试过了,当_显示在$ rootScope中时,ng-repeat不会呈现任何内容。
保罗

49

我想让我的html保持最小,因此定义了一个小的过滤器来创建数组[0,1,2,...],就像其他人所做的那样:

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

之后,在视图上可以这样使用:

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

34

这确实很丑陋,但是它在没有用于整数或变量的控制器的情况下可以工作:

整数:

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

变量:

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

有史以来最好的黑客!谢谢
jannis'8

2
_ in (_ = []).length = 33; _ track by $index稍小
Fabricio

16

有很多方法可以做到这一点。我真的很想在控制器中使用逻辑,所以我创建了一个简单的指令来解决n次重复元素的问题。

安装:

该指令可以使用以下命令安装 bower install angular-repeat-n

例:

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

产生: 1234

它也可以使用范围变量来工作:

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

资源:

Github


1
他们应该考虑将此添加到正式的角度指令中
HarshaXsoad

13

这只是接受的答案的微小变化,但您实际上并不需要创建函数。仅在范围内导入“数组”:

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

请参阅此小提琴以获取实时示例。


4
最新(2016年),更清洁!
朱利安·马里格

9

最简单的答案:2行代码

JS(在您的AngularJS控制器中)

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

... repeatCount在此位置应出现的重复次数是多少。


1
我相信,如果在控制器中进行了更改,则不允许您更改HTML中的重复次数,除非您像其他答案一样将其包装在函数中。
trysis

@trysis:我不确定我是否理解您的问题,但是您应该repeatCount在HTML中替换为实际数字,只要该数字小于或等于MAX_REPEATS,这将允许您设置数字HTML中的重复项。
JellicleCat

1
我认为,这是限制ngRepeat指令的最优雅的方法。Array.prototype.slice应该始终在underscore.js之类的库(取决于浏览器的兼容性)之类的库上选择使用和惯用JS 。
Pat Migliaccio

+1是一个不错的解决方案,但我认为这个答案更容易,并且避免了控制器混乱。
maxathousand

8

angular提供了一个非常漂亮的功能,称为slice ..使用此功能,您可以实现所需的功能。 例如ng-repeat =“ ab。abc.slice(startIndex,endIndex)”

此演示:http : //jsfiddle.net/sahilosheal/LurcV/39/将帮助您,并告诉您如何使用此“使生活变得轻松”功能。:)

的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

这是角1.2.x的答案

基本上是相同的,只是对 ng-repeat

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

这是小提琴:http : //jsfiddle.net/cHQLH/153/

这是因为angular 1.2不允许在指令中重复值。这意味着,如果您尝试执行以下操作,将会收到错误消息。

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

6

您可以将ng-if指令与ng-repeat

因此,如果num是您需要重复元素的次数:

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

1
对于那些喜欢纯净标记的人...请记住,ng-repeat以这种方式使用仍会输出带有注释的标记(<!-- ngIf: $index < num -->等)。liDOM 根本不会呈现任何元素。在此处结果窗格中检查“查看源代码”,以了解我的意思。

3

您可以使用此示例。

内部控制器:

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

HTML代码端的select元素示例:

<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

对于使用CoffeeScript的用户,您可以使用范围理解:

指示

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

或控制器

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

模板

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

3

扩展一下Ivan的第一个答案,只要字符是唯一的,就可以使用字符串作为集合,而无需跟踪语句,只要字符是唯一的,那么如果用例少于10个数字,我将简单地这样做:

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

可以肯定的是,这有点令人生疏,但看起来很简单,并且没有造成特别的混乱。


2

首先,使用LoDash创建角度滤镜:

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

LoDash时间功能能够处理null,undefined,0,数字和数字的字符串表示形式。

然后,按如下所示在HTML中使用它:

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

要么

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

1

我需要一个更动态的解决方案-在这里我可以增加重复次数。

的HTML

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

复印机控制

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

1

Angular提供了用于修改集合的过滤器。在这种情况下,集合将为空,即[],并且过滤器还接受参数,如下所示:

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

该方法与上面提出的方法非常相似,不一定优越,但显示了AngularJS中过滤器的功能。


1

如果n不太高,另一种选择是使用带有n个字符的字符串的split(''):

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

我认为在这里不需要拆分。字符串已经是字符数组。
忽略了

1

我遇到了同样的问题,这就是我想到的:

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

...和html:

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

现场例子

times在项目中已经使用下划线的功能,但是您可以轻松地用本机代码替换下划线的功能。


0

我正在创建一个可重用的指令,其中最大数量将来自另一个ng-repeat。因此,这是对最佳投票答案的编辑。

只需将控制器上的代码更改为此-

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

这将返回具有指定迭代次数的新数组


0

因为遍历一个字符串,它将为每个字符渲染一个项目:

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

我们可以使用本地过滤器使用这种丑陋但没有代码的解决方法number|n decimal places

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

这样,我们将拥有mynumber没有额外代码的元素。说'0.000'
我们mynumber - 2用来补偿0.
它不适用于3以下的数字,但在某些情况下可能有用。


你用了track by $index吗?
伊万·费雷尔别墅

这是贫民窟。如果您被迫每次迭代都有一个char,那么您也可以这样做ng-repeat="i in [1,2,3,4]"
Roi

当然,但是OP希望基于变量将迭代进行n次$scope.number
Ivan Ferrer Villa

为什么不使用“ abcd”而不是“ aaaa”,然后取消跟踪?
忽略了

aaaa是一个说明我(不是很优雅)解决方法的示例。使用硬编码的“ aaaa”或“ abcd”会得到固定长度的列表,但是将mynumber-2小数添加到0会得到带有mynumber字符的“字符串” 。说mynumber=5,您得到了'0.000',然后我们使用$ index进行迭代
Ivan Ferrer Villa

0
$scope.number = 5;

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

-1

简单方法:

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

在组件/控制器中,然后:

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

这段代码来自我的打字稿项目,但可以重新排列为纯JavaScript

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.