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>
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>
Je suis venu avec une version encore plus simple, pour créer une plage entre deux nombres définis, par exemple. 5 à 15
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;
};
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
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>
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
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>
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>
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>
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
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,
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 }}
Sans aucun changement dans votre contrôleur, vous pouvez utiliser ceci:
ng-repeat="_ in ((_ = []) && (_.length=51) && _) track by $index"
Profitez!
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>
Très simple:
$scope.totalPages = new Array(10);
<div id="pagination">
<a ng-repeat="i in totalPages track by $index">
{{$index+1}}
</a>
</div>
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>
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
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
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>
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>
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.
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>
<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.
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>