숫자 및 범위가있는 AngularJS For 루프


252

Angular는 HTML 지시문 내에서 숫자를 사용하여 for 루프를 지원합니다.

<div data-ng-repeat="i in [1,2,3,4,5]">
  do something
</div>

그러나 범위 변수에 동적 숫자가 포함 된 범위가 포함되어 있으면 매번 빈 배열을 만들어야합니다.

컨트롤러에서

var range = [];
for(var i=0;i<total;i++) {
  range.push(i);
}
$scope.range = range;

HTML에서

<div data-ng-repeat="i in range">
  do something
</div>

이것은 작동하지만 루프 내에서 범위 배열을 전혀 사용하지 않기 때문에 불필요합니다. 누구든지 최소 ​​/ 최대 값의 범위 또는 규칙을 설정하는 것을 알고 있습니까?

다음과 같은 것 :

<div data-ng-repeat="i in 1 .. 100">
  do something
</div>

2
여기에 대한 자세한 정보가 있습니다. yearofmoo.com/2012/10/…
matsko

답변:


281

나는 이 대답 을 약간 조정 하고이 바이올린을 생각해 냈다 .

다음과 같이 정의 된 필터 :

var myApp = angular.module('myApp', []);
myApp.filter('range', function() {
  return function(input, total) {
    total = parseInt(total);

    for (var i=0; i<total; i++) {
      input.push(i);
    }

    return input;
  };
});

반복이 다음과 같이 사용되면 :

<div ng-repeat="n in [] | range:100">
  do something
</div>

재미있는 Chrome을 사용하는 바이올린에 오류가 표시되지 않습니다. 어떤 브라우저?
Gloopy

5
무서운! ;) 필터는 이것을 수행하는 방법이 아닙니다. 두 가지 값으로 작동하는 새로운 속성이어야 합니다. 현재 인덱스와 상한
Ian Warburton

10
@IanWarburton 귀하의 기준에 맞는 답변을 얻을 수 있습니까?
dewd

1
@IanWarburton : 아래 지시문과 함께 작동하는 Уmed의 답변이 있습니다.
Andresch Serj

1
나는 A와 B 사이의 범위가 필요했기 때문에이 답변을 tweeked했습니다. jsfiddle.net/h9nLc8mk
Marcio

150

예를 들어 정의 된 두 숫자 사이의 범위를 만들기 위해 더 간단한 버전을 생각해 냈습니다. 5 ~ 15

JSFiddle 데모보기

HTML :

<ul>
    <li ng-repeat="n in range(5,15)">Number {{n}}</li>
</ul>

컨트롤러 :

$scope.range = function(min, max, step) {
    step = step || 1;
    var input = [];
    for (var i = min; i <= max; i += step) {
        input.push(i);
    }
    return input;
};

14
이런 것들을 조심해야합니다. 범위 함수는 목록의 각 항목에 대해 여러 번 호출됩니다. 과도한 메모리 누수가 발생할 수 있으며 많은 함수 호출이 생성됩니다. 컨트롤러 안에 컬렉션을 넣는 것이 거의 더 쉬운 것 같습니다.
Lucas Holt

1
var a; void 0 === a"정말로"정의되지 않았습니다.
andlrc

1
메모 라이저 패턴을 통해 결과를 캐싱하여 성능 저하를 줄일 수 있습니다. 메모리 비용이 얼마인지 확실하지 않지만 개선 된 것입니다. en.wikipedia.org/wiki/Memoization .
Joshua

1
@LucasHolt 마지막으로이 예제를 업데이트했습니다. 최적화 된 버전을 추가했습니다. 여전히 많은 함수 호출이 있지만 첫 번째 결과를 재사용하여 훨씬 더 성능이 좋습니다.
sqren

93

평범한 자바 스크립트 외에는 아무것도 없습니다 (컨트롤러가 필요하지 않음).

<div ng-repeat="n in [].constructor(10) track by $index">
    {{ $index }}
</div>

목업시 매우 유용


Angular> 1.2.1에서 작동하지 않음 : 콘솔 에이 오류가 Referencing "constructor" field in Angular expressions is disallowed! Expression: [].constructor(10)있습니다. 어쩌면 이전 버전의 Angular에서 작동했거나 잘못된 일을하고 있습니다.
AWolf

1.3 또는 1.4에서 이것을 테스트했다고 생각합니다. 파서가 개선되어 모든 '생성자'접근을 거부하지는 않지만 실제로 위험한 것 (예 : [].slice.constructor에 대한 액세스를 제공 Function하므로 코드 평가)을 거부합니다 .
Maël Nison

알았어 고마워. 1.2.1로 테스트했지만 작동하지 않습니다 (jsFiddle 드롭 다운에 포함 된 버전). 그러나 1.3.15에서는 작동합니다. 이 jsFiddle을 참조하십시오 .
AWolf April

페이지 매김에 매우 유용합니다. 감사합니다;)
낯선 사람

69

나는 조금 더 다른 구문을 생각해 냈고, 조금 더 적합하고 선택적인 하한값을 추가했습니다.

myApp.filter('makeRange', function() {
        return function(input) {
            var lowBound, highBound;
            switch (input.length) {
            case 1:
                lowBound = 0;
                highBound = parseInt(input[0]) - 1;
                break;
            case 2:
                lowBound = parseInt(input[0]);
                highBound = parseInt(input[1]);
                break;
            default:
                return input;
            }
            var result = [];
            for (var i = lowBound; i <= highBound; i++)
                result.push(i);
            return result;
        };
    });

당신이 사용할 수있는

<div ng-repeat="n in [10] | makeRange">Do something 0..9: {{n}}</div>

또는

<div ng-repeat="n in [20, 29] | makeRange">Do something 20..29: {{n}}</div>

이것은 훌륭하지만 $digest범위가 지정된 값을 사용할 때 모든 반복을 ng-repeat="n in [1, maxValue] | makeRange"어떻게 처리합니까?
pspahn

한 두 개의 PARAM의 경우 치료가 다르게 highBound, 그것은 일관성이 있어야합니다
Vajk Hermecz

31

angularjs를 처음 사용하는 사람들을 위해. 인덱스는 $ index를 사용하여 얻을 수 있습니다.

예를 들면 다음과 같습니다.

<div ng-repeat="n in [] | range:10">
    do something number {{$index}}
</div>

당신이 Gloopy의 편리한 필터를 사용할 때 어느, 인쇄됩니다 :
무언가 번호 0
무언가 번호 1
무언가 번호 2
무언가 번호 3
무언가 번호 4
무언가 번호 5
무언가 번호 6
무언가 번호 7
무언가 번호 (8)
9 번을 해봐


7
그러나이 경우 do something number {{n}}에도 충분합니다.
captncraig

2
Chrome에서이 코드를 실행하려고하면 콘솔에 오류가 발생합니다. 오류 : [$ injector : unpr] errors.angularjs.org/1.2.6/$injector/… ... ... Wa.statements ( ajax.googleapis.com/ajax/libs/angularjs/1.2.6/… ) <!-ngRepeat : n in [] | range : 10-> (불행히도 전체 오류가 너무 길어서 허용 된 주석 길이에 맞지 않기 때문에 첫 번째와 마지막 줄을 복사했습니다)
Kmeixner

1
코드와 비교할 수 있도록 코드의 Plunker 예제를 만들었습니다. plnkr.co/edit/tN0156hRfX0M6k9peQ2C?p= 미리보기
Arnoud Sietsema

21

이를 수행하는 간단한 방법은 Underscore.js의 _.range () 메소드를 사용하는 것입니다. :)

http://underscorejs.org/#range

// declare in your controller or wrap _.range in a function that returns a dynamic range.
var range = _.range(1, 11);

// val will be each number in the array not the index.
<div ng-repeat='val in range'>
    {{ $index }}: {{ val }}
</div>

1
@jwoodward 그는 옵션이 아니라고 말한 적이 없다. 내 솔루션은 저장소의 단위 테스트 덕분에 가장 간단하고 가장 테스트되었습니다. 항상 j를 축소되지 않은 라이브러리에서 꺼내 함수로 포함시킬 수 있습니다.
마이클 J. 칼 킨스

4
사실, 그는 그런 말을 한 적이 없습니다. 그러나 일반적으로 다른 라이브러리를 적용하여 한 라이브러리에서 문제를 해결하는 것은 좋지 않습니다. 첫 번째 라이브러리를 올바르게 사용하는 방법을 배우지 못합니다. 현재 라이브러리에 적합한 솔루션이없는 경우 다른 라이브러리로 전환하십시오.
Erik Honn

5
나는 이미 모든 곳에서 lodash를 사용하고 있으며, 이것은 가장 쉬운 해결책이었습니다. 감사합니다. 방금 $ scope.range = _.range를 수행 한 다음 동적 시작 / 종료 값을 가진 모든 템플릿에서 사용하기 쉽습니다.
j_walker_dev

2
@ErikHonn : UnderscoreJS는 AngularJS와 완전히 다른 문제를 해결합니다. AngularJS에서 범위를 생성하는 좋은 해결책은 라이브러리의 목적이 아니기 때문에 없습니다.
AlexFoxGill 2016 년

2
이것은 오래되었지만 의미가없는 방식으로 현재 라이브러리의 기능을 남용하는 대신 범위 생성과 같은 작업을 수행하도록 설계된 라이브러리를 사용하는 것이 훨씬 더 좋은 방법입니까? 물론 무언가를 배울 수도 있지만 다른 것을 위해 설계된 것들의 왜곡 된 사용법으로 끝납니다.
Dan

20

내 사용자 지정 ng-repeat-range지시문을 사용 합니다.

/**
 * Ng-Repeat implementation working with number ranges.
 *
 * @author Umed Khudoiberdiev
 */
angular.module('commonsMain').directive('ngRepeatRange', ['$compile', function ($compile) {
    return {
        replace: true,
        scope: { from: '=', to: '=', step: '=' },

        link: function (scope, element, attrs) {

            // returns an array with the range of numbers
            // you can use _.range instead if you use underscore
            function range(from, to, step) {
                var array = [];
                while (from + step <= to)
                    array[array.length] = from += step;

                return array;
            }

            // prepare range options
            var from = scope.from || 0;
            var step = scope.step || 1;
            var to   = scope.to || attrs.ngRepeatRange;

            // get range of numbers, convert to the string and add ng-repeat
            var rangeString = range(from, to + 1, step).join(',');
            angular.element(element).attr('ng-repeat', 'n in [' + rangeString + ']');
            angular.element(element).removeAttr('ng-repeat-range');

            $compile(element)(scope);
        }
    };
}]);

HTML 코드는

<div ng-repeat-range from="0" to="20" step="5">
    Hello 4 times!
</div>

또는 단순히

<div ng-repeat-range from="5" to="10">
    Hello 5 times!
</div>

또는 단순히

<div ng-repeat-range to="3">
    Hello 3 times!
</div>

아니면 그냥

<div ng-repeat-range="7">
    Hello 7 times!
</div>

1
이론적으로는 좋지만 주입이 element.attr('ng-repeat', 'n in [' + rangeString + ']');작동하지 않습니다 ...
Stefan Walther

"나는 사용한다...". 실제로 사용하려고 했습니까? ng-repeat 속성은 컴파일되지 않습니다.
Peter Hedberg

고마워 Peter, 나는 코드를 업데이트했다. 나는 과거에이 지시자를 사용하지만 여전히 내 코드 저장소 왼쪽
pleerock

9

가장 간단한 코드 솔루션은 범위가없는 배열을 초기화하고 $ index +를 사용했지만 오프셋으로 많이 사용하고 싶었습니다.

<select ng-init="(_Array = []).length = 5;">
    <option ng-repeat="i in _Array track by $index">{{$index+5}}</option>
</select>

7

분석법 정의

아래 코드는 range()응용 프로그램의 전체 범위에서 사용할 수 있는 방법을 정의합니다 MyApp. 동작은 Python range()메소드 와 매우 유사합니다 .

angular.module('MyApp').run(['$rootScope', function($rootScope) {
    $rootScope.range = function(min, max, step) {
        // parameters validation for method overloading
        if (max == undefined) {
            max = min;
            min = 0;
        }
        step = Math.abs(step) || 1;
        if (min > max) {
            step = -step;
        }
        // building the array
        var output = [];
        for (var value=min; value<max; value+=step) {
            output.push(value);
        }
        // returning the generated array
        return output;
    };
}]);

용법

하나의 매개 변수로 :

<span ng-repeat="i in range(3)">{{ i }}, </span>

0, 1, 2,

두 개의 매개 변수로 :

<span ng-repeat="i in range(1, 5)">{{ i }}, </span>

1, 2, 3, 4,

세 개의 매개 변수로 :

<span ng-repeat="i in range(-2, .7, .5)">{{ i }}, </span>

-2, -1.5, -1, -0.5, 0, 0.5,


6

angular.filter 모듈에서 'after'또는 'before'필터를 사용할 수 있습니다 ( https://github.com/a8m/angular-filter )

$scope.list = [1,2,3,4,5,6,7,8,9,10]

HTML :

<li ng-repeat="i in list | after:4">
  {{ i }}
</li>

결과 : 5, 6, 7, 8, 9, 10


6

컨트롤러를 변경하지 않고 다음을 사용할 수 있습니다.

ng-repeat="_ in ((_ = []) && (_.length=51) && _) track by $index"

즐겨!


하루 이상 고군분투하고 마지막 으로이 구문 만이 나를 위해 일했다
Agnel Amodia

3

최단 답변 : 2 줄의 코드

JS (AngularJS 컨트롤러에서)

$scope.range = new Array(MAX_REPEATS); // MAX_REPEATS should be the most repetitions you will ever need in a single ng-repeat

HTML

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

... myCount이 위치에 나타날 별의 수는 어디 입니까?

$index모든 추적 작업에 사용할 수 있습니다 . 예를 들어 인덱스에 약간의 돌연변이를 인쇄하려면 다음에 다음을 입력하십시오 div.

{{ ($index + 1) * 0.5 }}

2

UnderscoreJS 사용 :

angular.module('myModule')
    .run(['$rootScope', function($rootScope) { $rootScope.range = _.range; }]);

이것을 적용하면 $rootScope어디서나 사용할 수 있습니다.

<div ng-repeat="x in range(1,10)">
    {{x}}
</div>

2

매우 간단한 것 :

$scope.totalPages = new Array(10);

 <div id="pagination">
    <a ng-repeat="i in totalPages track by $index">
      {{$index+1}}
    </a>   
 </div> 

2

안녕하세요, AngularJS를 사용하여 순수한 HTML을 사용 하여이 작업을 수행 할 수 있습니다 (지침이 필요하지 않습니다!)

<div ng-app="myapp" ng-controller="YourCtrl" ng-init="x=[5];">
  <div ng-if="i>0" ng-repeat="i in x">
    <!-- this content will repeat for 5 times. -->
    <table class="table table-striped">
      <tr ng-repeat="person in people">
         <td>{{ person.first + ' ' + person.last }}</td>
      </tr>
    </table>
    <p ng-init="x.push(i-1)"></p>
  </div>
</div>

1

컨트롤러에서 범위 설정

var range = [];
for(var i=20;i<=70;i++) {
  range.push(i);
}
$scope.driverAges = range;

HTML 템플릿 파일에서 반복 설정

<select type="text" class="form-control" name="driver_age" id="driver_age">
     <option ng-repeat="age in driverAges" value="{{age}}">{{age}}</option>
</select>

1

@Mormegil 솔루션 개선

app.filter('makeRange', function() {
  return function(inp) {
    var range = [+inp[1] && +inp[0] || 0, +inp[1] || +inp[0]];
    var min = Math.min(range[0], range[1]);
    var max = Math.max(range[0], range[1]);
    var result = [];
    for (var i = min; i <= max; i++) result.push(i);
    if (range[0] > range[1]) result.reverse();
    return result;
  };
});

용법

<span ng-repeat="n in [3, -3] | makeRange" ng-bind="n"></span>

3 2 1 -1 -2 -3

<span ng-repeat="n in [-3, 3] | makeRange" ng-bind="n"></span>

-3-2-1-1 2 3

<span ng-repeat="n in [3] | makeRange" ng-bind="n"></span>

012 3

<span ng-repeat="n in [-3] | makeRange" ng-bind="n"></span>

0-1-2-3


1

나는 다음을 시도했고 그것은 나를 위해 잘 작동했다.

<md-radio-button ng-repeat="position in formInput.arrayOfChoices.slice(0,6)" value="{{position}}">{{position}}</md-radio-button>

각도 1.3.6


1

파티에 늦었다. 그러나 나는 이것을 그냥 끝내었다.

컨트롤러에서 :

$scope.repeater = function (range) {
    var arr = []; 
    for (var i = 0; i < range; i++) {
        arr.push(i);
    }
    return arr;
}

HTML :

<select ng-model="myRange">
    <option>3</option>
    <option>5</option>
</select>

<div ng-repeat="i in repeater(myRange)"></div>

1

이것은 jzm의 개선 된 답변입니다 (나는 오류가 포함되어 있기 때문에 그녀의 답변을 언급 할 수는 없습니다). 이 함수는 시작 / 종료 범위 값을 가지므로 더 유연하고 작동합니다. 이 특별한 경우는 다음과 같습니다.

$scope.rangeCreator = function (minVal, maxVal) {
    var arr = [];
   for (var i = minVal; i <= maxVal; i++) {
      arr.push(i);
   }
   return arr;
};


<div class="col-sm-1">
    <select ng-model="monthDays">
        <option ng-repeat="day in rangeCreator(1,31)">{{day}}</option>
    </select>
</div>

0

나는 이것을 채찍질하고 그것이 일부에게 유용 할 수 있음을 보았다. (예, CoffeeScript. 고소합니다.)

지령

app.directive 'times', ->
  link: (scope, element, attrs) ->
    repeater = element.html()
    scope.$watch attrs.times, (value) ->
      element.html ''
      return unless value?
      element.html Array(value + 1).join(repeater)

쓰다:

HTML

<div times="customer.conversations_count">
  <i class="icon-picture></i>
</div>

이것이 더 간단해질 수 있습니까?

Angular는 항상 좋은 이유없이 필터를 다시 평가하기를 좋아하기 때문에 필터에 대해주의를 기울이고 있습니다. 여러분과 같이 수천 개가 있으면 큰 병목 현상이 발생합니다.

이 지시문은 모델의 변경 사항을 감시하고 그에 따라 요소를 업데이트합니다.


이것은 좋지만 ngRepeat는 자체 범위를 유지합니다. 따라서 추가 된 각 항목에 대해 컴파일을 실행해야합니다. ngRepeat가 대신하기 때문에 애니메이션을 에뮬레이션해야합니다.
matsko

2
기여해 주셔서 감사하지만 OP가 커피 스크립트, 그것이 무엇인지, JS로 다시 컴파일하는 방법을 알고 있거나 그와 같은 빌드 도구를 사용한 적이 있다고 가정합니다. 우리는 모두 배우거나 돕기 위해 여기에 있습니다. 그래서 여분의 마일로 가서 강아지를 개조하십시오. (당신은 고소되었습니다!)
Augie Gardner

0
<div ng-init="avatars = [{id : 0}]; flag = true ">
  <div ng-repeat='data in avatars' ng-if="avatars.length < 10 || flag"
       ng-init="avatars.length != 10 ? avatars.push({id : $index+1}) : ''; flag = avatars.length <= 10 ? true : false">
    <img ng-src="http://actual-names.com/wp-content/uploads/2016/01/sanskrit-baby-girl-names-400x275.jpg">
  </div>
</div>

컨트롤러 또는 공장없이 html 로이 작업을 수행하려는 경우.


0

$scope.refernceurl그런 다음 배열 이라고 가정

for(var i=0; i<$scope.refernceurl.length; i++){
    $scope.urls+=$scope.refernceurl[i].link+",";
}

-8

이것은 가장 간단한 변형입니다 : 정수 배열을 사용하십시오 ...

 <li ng-repeat="n in [1,2,3,4,5]">test {{n}}</li>


3
이것은 끔찍하다.
Tiffany Lowe

@Stefan, 솔루션에서 하드 코딩 된 컬렉션을 사용할 수 없기 때문에 다운 보트를받을 수 있습니다.
Tass
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.