AngularJS pour boucle avec nombres et plages

Angular fournit un certain support pour une boucle for utilisant des nombres dans ses directives HTML:

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

Mais si votre variable scope inclut une plage qui a un nombre dynamique, vous devrez créer un tableau vide à chaque fois.

Dans le contrôleur

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

Dans le HTML

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

Cela fonctionne, mais c'est inutile car nous n'utiliserons pas du tout le tableau range dans la boucle. Est-ce que quelqu'un sait de définir une plage ou un régulier pour la valeur min/max?

Quelque Chose comme:

<div data-ng-repeat="i in 1 .. 100">
  do something
</div>
235
demandé sur domino_katrino 2012-08-09 01:37:27

23 réponses

J'ai modifié cette réponse un peu et est venu avec ce violon.

Filtre défini comme:

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

Avec la répétition utilisée comme ceci:

<div ng-repeat="n in [] | range:100">
  do something
</div>
258
répondu Gloopy 2017-05-23 12:34:29

Je suis venu avec une version encore plus simple, pour créer une plage entre deux nombres définis, par exemple. 5 à 15

Voir la démo sur JSFiddle

HTML:

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

Contrôleur de:

$scope.range = function(min, max, step) {
    step = step || 1;
    var input = [];
    for (var i = min; i <= max; i += step) {
        input.push(i);
    }
    return input;
};
139
répondu sqren 2017-05-03 10:50:57

Rien que du JavaScript simple (vous n'avez même pas besoin d'un contrôleur):

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

Très utile lors de la maquette

80
répondu Maël Nison 2015-02-26 16:55:36

J'ai trouvé une syntaxe légèrement différente qui me convient un peu plus et ajoute également une limite inférieure facultative:

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

Que vous pouvez utiliser comme

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

Ou

<div ng-repeat="n in [20, 29] | makeRange">Do something 20..29: {{n}}</div>
67
répondu Mormegil 2013-02-18 08:47:42

Pour les nouveaux à angularjs. L'indice peut être obtenu en utilisant $index.

Par exemple:

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

Qui, lorsque vous utilisez le filtre pratique de Gloopy, imprimera:
faire quelque chose numéro 0
faire quelque chose numéro 1
faire quelque chose numéro 2
faire quelque chose numéro 3
faire quelque chose numéro 4
faire quelque chose numéro 5
faire quelque chose numéro 6
faire quelque chose numéro 7
faire quelque chose numéro 8
faire quelque chose numéro 9

30
répondu Arnoud Sietsema 2013-02-04 20:40:00

Une courte façon de le faire serait d'utiliser Underscore.js's _.méthode 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>
21
répondu Michael J. Calkins 2013-09-26 14:37:35

J'utilise ma directive personnalisée 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);
        }
    };
}]);

Et le code html est

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

, Ou simplement

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

, Ou même simplement

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

Ou juste

<div ng-repeat-range="7">
    Hello 7 times!
</div>
19
répondu pleerock 2014-09-29 20:05:49

La solution la plus simple sans code était d'initialiser un tableau avec la plage, et d'utiliser l'index $ + autant que je veux compenser par:

<select ng-init="(_Array = []).length = 5;">
    <option ng-repeat="i in _Array track by $index">{{$index+5}}</option>
</select>
9
répondu Vince 2015-01-29 18:49:51

Vous pouvez utiliser "après" ou "avant" filtres angulaire.module de filtre (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>

Résultat: 5, 6, 7, 8, 9, 10

6
répondu a8m 2014-07-17 10:21:40

Définition de la méthode

Le code ci-dessous définit une méthode range() Disponible pour l'ensemble de votre application MyApp. Son comportement est très similaire au Python range() méthode.

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

Utilisation

Avec un paramètre:

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

0, 1, 2,

, Avec deux paramètres:

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

1, 2, 3, 4,

, Avec trois paramètres:

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

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

5
répondu Mathieu Rodic 2018-03-12 11:48:49

Réponse la plus courte: 2 lignes de code

JS (dans votre contrôleur 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>

...où myCount est le nombre d'étoiles qui devrait apparaître à cet endroit.

, Vous pouvez utiliser $index pour toutes les opérations de suivi. Par exemple, si vous voulez imprimer une mutation sur l'index, vous pouvez mettre ce qui suit dans le div:

{{ ($index + 1) * 0.5 }}
3
répondu JellicleCat 2014-12-10 18:19:50

Sans aucun changement dans votre contrôleur, vous pouvez utiliser ceci:

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

Profitez!

3
répondu odroz 2016-05-22 07:31:31

En Utilisant UnderscoreJS:

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

L'appliquer à $rootScope le rend disponible partout:

<div ng-repeat="x in range(1,10)">
    {{x}}
</div>
2
répondu AlexFoxGill 2014-06-24 14:34:19

Très simple:

$scope.totalPages = new Array(10);

 <div id="pagination">
    <a ng-repeat="i in totalPages track by $index">
      {{$index+1}}
    </a>   
 </div> 
2
répondu Evan Hu 2015-01-17 01:23:57

Définir la portée dans le contrôleur

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

Définir la répétition dans le fichier de modèle 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
répondu Ahmer 2014-09-11 20:23:35

Une amélioration de la solution de @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;
  };
});

Utilisation

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

3 2 1 0 -1 -2 -3

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

-3 -2 -1 0 1 2 3

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

0 1 2 3

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

0 -1 -2 -3

1
répondu theliberalsurfer 2014-11-29 01:02:35

J'ai essayé ce qui suit et cela a très bien fonctionné pour moi:

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

Angulaire 1.3.6

1
répondu araghorn 2015-04-09 14:49:04

C'est la réponse améliorée de jzm (Je ne peux pas commenter sinon je commenterais sa réponse parce qu'il a inclus des erreurs). La fonction a une valeur de plage de début/fin, il est donc plus flexible, et... elle fonctionne. Ce cas particulier est pour le jour du mois:

$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>
1
répondu fresko 2016-03-09 12:24:02

Salut, vous pouvez y parvenir en utilisant du html pur en utilisant AngularJS (aucune Directive n'est requise!)

<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
répondu Pavan Kosanam 2016-08-02 05:25:48

J'ai fouetté cela et j'ai vu que cela pourrait être utile pour certains. (Oui, CoffeeScript. Me poursuivre en justice.)

Directive

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)

À utiliser:

HTML

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

Cela peut-il être plus simple?

Je me méfie des filtres car Angular aime les réévaluer sans raison valable tout le temps, et c'est un énorme goulot d'étranglement si vous en avez des milliers comme moi.

Cette directive surveillera même les changements dans votre modèle et mettra à jour l'élément en conséquence.

0
répondu Prathan Thananart 2013-06-27 03:25:19

En retard à la fête. Mais j'ai fini par faire ceci:

Dans votre contrôleur:

$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>
0
répondu jzm 2015-12-15 23:33:46
<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>

Si vous voulez y parvenir en html sans contrôleur ou usine.

0
répondu Virendra Singh Rathore 2016-06-27 12:03:50

C'est la variante la plus simple: utilisez simplement tableau d'entiers....

 <li ng-repeat="n in [1,2,3,4,5]">test {{n}}</li>
-7
répondu Stefan 2015-06-05 16:09:41