配列を繰り返すのではなく、定義された回数をng-repeatする方法?


417

ng-repeat常に配列を反復処理する必要がない代わりに、定義された回数を実行する方法はありますか?

たとえば、以下では、リストアイテムが$scope.number5に等しいと仮定して、リストアイテムを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>


回答:


569

アップデート(2018年9月25日)

AngularJSの新しいバージョン(> = 1.3.0)では、これを変数のみで実行できます(関数は必要ありません)。

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

これは、最初に質問された時点では不可能でした。この更新に関する以下の回答から@Nikhil Nambiarへの謝辞


オリジナル(2013年5月29日)

現時点では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応じて任意の数に変更し、探しているバインディングを維持できます。

編集(2014年1月6日)-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年

リストはいくつでも機能します。このフィドルを
Dan

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); } xを返します。} //数値が動的に変化するときにこの関数を使用する
Manavendher

1
@ sh0ber。数値ドロップダウンで選択した値に基づいてリストアイテムを変更する必要がある場合。私は最初にあなたの機能を試しました、それが機能していないとき、私はそれを上記に変更してnoを更新しました。ドロップダウンで別の番号が選択されている場合のリストアイテムの数。あなたの関数を使って私のシナリオを確認してください。
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

1
この回答に記載されているように、動的長配列の配列コンストラクターを呼び出すことを検討してください。
maxathousand

120回繰り返す必要がある場合 [1,2,3 ... 120]でいいですか?
Munkhdelger Tumenbayar

94

これを行う方法の例を次に示します。ng-repeat docsのコメントに触発されたことに注意してください: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);
午後

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:items.slice(3,6)など
trevorc

7
この回答により、コントローラーのフットプリントが最小になります。Angularアプローチも推奨されます。IMOで承認された回答はこれに置き換える必要があります。
Matt Jensen、

1
これは(私の意見では)受け入れられる答えであるはずです-最もエレガントで、最も好まれます。
コーディ

11
@コーディ残念ながら、それは質問に答えません。OPは「常に配列を反復処理する必要はなく」、「$scope.number5 と想定」と述べています。その目的は、整数変数を使用して項目数を定義することであり、ハードコードしたり、事前定義された配列を使用したりすることではありませんでした。
ダン、

5
@Cody @ sh0berスコープ($scope.limit = 2)に制限を設定して、次のように使用でき...|limitTo:limitます。更新されたフィドルを
drzaus

58

より簡単な方法は次のとおりです(5回の例の場合):

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

5
鮮やかさ。新しい配列を返すために、コントローラーで読み取り可能で短く、馬鹿げた機能はありません。
maxathousand

2
私はこのように大好きです。
Rabbi Shuki Gur

質問が最初に尋ねられたとき(Angular 1.2)、これは不可能でした。これを含めるために、受け入れられた回答を変更しました。良くやった!
Dan

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
これは良いことですが、下線はデフォルトではスコープ内にないことに注意してください$scope._ = _
jedd.ahyoung

6
lodashまたはunderscoreを使用している場合は、$rootScopeどこにでも使用できるように配置する必要があります。これをapp.run関数の直後に置きますapp.configapp.run(function ($rootScope) { $rootScope._ = _; });
ジェレミー・モリッツ

これは私にとって完璧な答えでした。シンプルで非常に簡単です。カウントのある変数を使用して繰り返していたので、_。range(1、count + 1)でng-repeat = "nを実行する必要がありました。解決策をありがとう
Darryl

私はこれを試してみましたが、_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

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)で、よりクリーンに!
Julien Malige 16

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:問題を理解しているかどうかはわかりませんrepeatCountが、HTML内の実際の数値に置き換える必要があります。その数値が以下である限りMAX_REPEATS、これにより数値を設定できますHTMLでの繰り返しの。
JellicleCat 2016

1
私の意見では、これはngRepeat指令を制限する最もエレガントな方法です。使用Array.prototype.sliceしている慣用的なJSは、常に underscore.js(ブラウザーの互換性に依存)などのライブラリよりも選択する必要があります。
Pat Migliaccio 2017

悪い解決策ではありません、+ 1、しかし私はこの答えがより簡単で、コントローラーが乱雑になるのを避けていると思います。
maxathousand

8

angularは、sliceと呼ばれる非常に甘い機能を提供します。これを使用して、目的の機能を実現できます。 例:ng-repeat = "ab in 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のtimes関数は、null、未定義、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はコレクションを修正するためのフィルターを提供します。この場合、コレクションはnull、つまり[]になり、フィルターは次のように引数も受け取ります。

<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
Ivan Ferrer Villa

これはゲットーafです。イテレーションごとにcharを持つことを余儀なくされる場合は、同様に行うことができますng-repeat="i in [1,2,3,4]"
Roi

もちろん、しかしOPは変数に基づいて反復がn回になることを望んでいます$scope.number
Ivan Ferrer Villa

なぜ「aaaa」ではなく「abcd」ではなく、トラックをスクラップするのですか?
19:12に省略

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

このコードは私のtypescriptプロジェクトからのものですが、純粋なjavascriptに再配置できます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.