angularjs - example - ¿Cómo repetir ng veces el número definido de veces en lugar de repetir sobre una matriz?
ng-repeat order by (25)
¿Hay alguna forma de repetir ng un número definido de veces en lugar de tener que iterar siempre sobre una matriz?
Por ejemplo, a continuación quiero que el elemento de la lista se muestre 5 veces asumiendo que $scope.number
igual a 5, además de incrementar el número para que cada elemento de la lista se incremente como 1, 2, 3, 4, 5
Resultado deseado:
<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>
La respuesta más fácil: 2 líneas de código.
JS (en tu controlador 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>
... donde repeatCount
es el número de repeticiones que deben aparecer en esta ubicación.
Ampliando un poco la primera respuesta de Ivan, puede usar una cadena como la colección sin una pista por declaración siempre y cuando los caracteres sean únicos, por lo que si el caso de uso es inferior a 10 números, como es la pregunta que simplemente haría :
<ul>
<li ng-repeat="n in ''12345''"><span>{{n}}</span></li>
</ul>
Que es un poco jenky, claro, pero lo suficientemente simple como para mirar y no particularmente confuso.
Angular proporciona filtros para modificar una colección. En este caso, la colección sería nula, es decir, [], y el filtro también toma argumentos, como sigue:
<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;
}]);
Este método es muy similar a los propuestos anteriormente y no es necesariamente superior, pero muestra el poder de los filtros en AngularJS.
Aquí hay un ejemplo de cómo podrías hacer esto. Tenga en cuenta que me inspiré en un comentario en los documentos de ng-repeat: http://jsfiddle.net/digitalzebra/wnWY6/
Tenga en cuenta la directiva ng-repeat:
<div ng-app>
<div ng-controller="TestCtrl">
<div ng-repeat="a in range(5) track by $index">{{$index + 1}}</div>
</div>
</div>
Aquí está el controlador:
function TestCtrl($scope) {
$scope.range = function(n) {
return new Array(n);
};
};
En este momento, ng-repeat
solo acepta una colección como parámetro, pero puede hacer esto:
<ul>
<li ng-repeat="i in getNumber(number)"><span>{{$index+1}}</span></li>
</ul>
Y en algún lugar de tu control:
$scope.number = 5;
$scope.getNumber = function(num) {
return new Array(num);
}
Esto le permitiría cambiar $scope.number
a cualquier número que desee y aún así mantener el enlace que está buscando.
Aquí hay un violín con un par de listas que utilizan la misma función getNumber
.
EDICIÓN 1/6/2014 : Las versiones más recientes de Angular 1.x hacen uso de la siguiente sintaxis:
<li ng-repeat="i in getNumber(number) track by $index">
EDITAR 9/25/2018 : Las versiones más recientes de Angular 1.x le permiten hacer esto sin una función. Si su código es simple y no necesita una función getNumber
por otras razones, ahora puede omitir eso y simplemente hacer esto:
<div ng-repeat="x in [].constructor(number) track by $index">
Gracias a @Nikhil Nambiar por su respuesta a continuación para esta actualización
Encontré el mismo problema y esto es con lo que salí:
(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();
}
}
})();
... y el html:
<div repeat-times="4">{{ $index }}</div>
Usé la función de times
de guión bajo como nosotros cuando ya lo usamos en el proyecto, pero puede reemplazarlo fácilmente con código nativo.
Esta es solo una pequeña variación en la respuesta aceptada, pero realmente no es necesario crear una nueva función. Solo para importar ''Array'' en el alcance:
<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;
});
Ver este violín para un ejemplo en vivo.
Esto es realmente malo, pero funciona sin un controlador para un entero o una variable:
entero:
<span ng-repeat="_ in ((_ = []) && (_.length=33) && _) track by $index">{{$index}}</span>
variable:
<span ng-repeat="_ in ((_ = []) && (_.length=myVar) && _) track by $index">{{$index}}</span>
Estoy creando una directiva reutilizable donde el número máximo provendrá de otra repetición ng. Por lo tanto, esta es una edición sobre la respuesta mejor votada.
Solo cambia el código en el controlador a esto -
$scope.getNumber = function(num) {
var temp = [];
for(var j = 0; j < num; j++){
temp.push(j)
}
return temp;
}
Esto devolverá una nueva matriz con un número especificado de iteraciones
Hay muchas maneras de hacer esto. Me molestó mucho tener la lógica en mi controlador, así que creé una directiva simple para resolver el problema de repetir un elemento n-veces.
Instalación:
La directiva se puede instalar utilizando la bower install angular-repeat-n
Ejemplo:
<span ng-repeat-n="4">{{$index}}</span
produce: 1234
También funciona utilizando una variable de alcance:
<span ng-repeat-n="repeatNum"></span>
Fuente:
Heres una respuesta para angular 1.2.x
Básicamente es lo mismo, con la ligera modificación de la ng-repeat
<li ng-repeat="i in getNumber(myNumber) track by $index">
Aquí está el violín: http://jsfiddle.net/cHQLH/153/
esto se debe a que angular 1.2 no permite valores duplicados en la directiva. Esto significa que si intenta hacer lo siguiente, obtendrá un error.
<li ng-repeat="x in [1,1,1]"></li>
Me encontré con el mismo problema. Encontré este hilo, pero no me gustaron los métodos que tenían aquí. Mi solución estaba usando underscore.js, que ya habíamos instalado. Es tan simple como esto:
<ul>
<li ng-repeat="n in _.range(1,6)"><span>{{n}}</span></li>
</ul>
Esto hará exactamente lo que estás buscando.
Necesitaba una solución más dinámica para esto, donde pudiera incrementar la repetición.
HTML
<div ng-repeat="n in newUserCount">
<input type="text" value="" name="newuser{{n}}"/>
</div>
Control duplicador
<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)
}
Para los usuarios que utilizan CoffeeScript, puede utilizar un rango de comprensión:
Directiva
link: (scope, element, attrs) ->
scope.range = [1..+attrs.range]
o controlador
$scope.range = [1..+$someVariable]
$scope.range = [1..5] # Or just an integer
Modelo
<div ng-repeat="i in range">[ the rest of your code ]</div>
Primero, crea un filtro angular usando LoDash:
angular.module(''myApp'').filter(''times'', function(){
return function(value){
return _.times(value || 0);
}
});
La función de tiempos de LoDash es capaz de manejar nulos, indefinidos, 0, números y representación de cadenas de números.
Entonces, utilízalo en tu HTML como esto:
<span ng-repeat="i in 5 | times">
<!--DO STUFF-->
</span>
o
<span ng-repeat="i in myVar | times">
<!--DO STUFF-->
</span>
Puede usar la directiva ng-if
con ng-repeat
Entonces, si num es el número de veces que necesita que se repita el elemento:
<li ng-repeat="item in list" ng-if="$index < num">
Puedes hacerlo:
<div ng-repeat="i in [1, 2, 3, 4]">
...
</div>
Puedes usar este ejemplo.
Controlador interno:
$scope.data = {
''myVal'': 33,
''maxVal'': 55,
''indexCount'': function(count) {
var cnt = 10;
if (typeof count === ''number'') {
cnt = count;
}
return new Array(cnt);
}
};
Ejemplo para seleccionar un elemento en el lado del código HTML:
<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>
Quería mantener mi html al mínimo, así que definí un pequeño filtro que crea la matriz [0,1,2, ...] como lo han hecho otros:
angular.module(''awesomeApp'')
.filter(''range'', function(){
return function(n) {
var res = [];
for (var i = 0; i < n; i++) {
res.push(i);
}
return res;
};
});
Después de eso, en la vista es posible usar así:
<ul>
<li ng-repeat="i in 5 | range">
{{i+1}} <!-- the array will range from 0 to 4 -->
</li>
</ul>
Si n no es demasiado alto, otra opción podría ser usar split ('''') con una cadena de n caracteres:
<div ng-controller="MainCtrl">
<div ng-repeat="a in ''abcdefgh''.split('''')">{{$index}}</div>
</div>
Un enfoque más simple sería (para un ejemplo de 5 veces):
<div ng-repeat="x in [].constructor(5) track by $index">
...
</div>
angular le da una función muy dulce llamada slice ... con esto puede lograr lo que está buscando. por ejemplo, ng-repeat = "ab en abc.slice (startIndex, endIndex)"
esta demostración: http://jsfiddle.net/sahilosheal/LurcV/39/ lo ayudará y le dirá cómo usar esta función de "facilitar la vida". :)
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''}];
}
desde la iteración de una cadena, se representará un elemento para cada carácter:
<li ng-repeat = "k in ''aaaa'' track by $index">
{{$index}} //THIS DOESN''T ANSWER OP''S QUESTION. Read below.
</li>
podemos usar esta solución alternativa fea pero sin código utilizando el filtro nativo de number|n decimal places
<li ng-repeat="k in (0|number:mynumber -2 ) track by $index">
{{$index}}
</li>
De esta manera tendremos mynumber
elementos sin código adicional. Diga ''0.000''
.
Usamos mynumber - 2
para compensar 0.
No funcionará con números inferiores a 3, pero puede ser útil en algunos casos.
manera simple:
public defaultCompetences: Array<number> = [1, 2, 3];
en el componente / controlador y luego:
<div ng-repeat="i in $ctrl.defaultCompetences track by $index">
Este código es de mi proyecto mecanografiado pero podría ser reorganizado a javascript puro