@Component({
(...)
template: `
<div *ngFor="let i of Arr(num).fill(1)"></div>
`
})
export class SomeComponent {
Arr = Array; //Array type captured in a variable
num:number = 20;
}
O implementar una tubería personalizada:
import {PipeTransform, Pipe} from '@angular/core';
@Pipe({
name: 'fill'
})
export class FillPipe implements PipeTransform {
transform(value) {
return (new Array(value)).fill(1);
}
}
@Component({
(...)
template: `
<div *ngFor="let i of num | fill"></div>
`,
pipes: [ FillPipe ]
})
export class SomeComponent {
arr:Array;
num:number = 20;
}
Esta debería ser la respuesta correcta. ¡Es, con mucho, la más concisa!
Mantisimo
ERROR RangeError: longitud de matriz no válida. Esto se bloqueará cuando el número de gatos para dibujar sea cero.
Tom Bevelander
¡Realmente me gusta ese enfoque simple!
F. Geißler
51
Hay dos problemas con las soluciones recomendadas que utilizan Arrays:
Es un desperdicio. En particular para grandes cantidades.
Tiene que definirlos en algún lugar, lo que resulta en mucho desorden para una operación tan simple y común.
Parece más eficiente definir a Pipe(una vez), devolviendo un Iterable:
import {PipeTransform, Pipe} from '@angular/core';
@Pipe({name: 'times'})
export class TimesPipe implements PipeTransform {
transform(value: number): any {
const iterable = <Iterable<any>> {};
iterable[Symbol.iterator] = function* () {
let n = 0;
while (n < value) {
yield ++n;
}
};
return iterable;
}
}
Ejemplo de uso (renderizado de una cuadrícula con ancho / alto dinámico):
<table>
<thead>
<tr>
<th *ngFor="let x of colCount|times">{{ x }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let y of rowCount|times">
<th scope="row">{{ y }}</th>
<td *ngFor="let x of colCount|times">
<input type="checkbox" checked>
</td>
</tr>
</tbody>
</table>
OP dijo que le asigna 20a una variable miembro .. así que esto no ayudará mucho
phil294
¿Y si quiero iterar 200 veces?
Chax
1
@Chax No puedes. :(
Muhammad bin Yusrat
2
@Chax ¿Qué pasa con 200? *ngFor="let number of [0,1,2,3,4,5...,199,200]":-D
Stack Underflow
1
@StackUnderflow Lamentablemente, no me pagan los personajes. Si lo fuera, predicaría que es la única manera de lograr eso: P (en serio, simplemente no lo hagas;))
Chax
10
Una solución más simple y reutilizable tal vez sea usar una directiva estructural personalizada como esta.
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[appTimes]'
})
export class AppTimesDirective {
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) { }
@Input() set appTimes(times: number) {
for (let i = 0 ; i < times ; i++) {
this.viewContainer.createEmbeddedView(this.templateRef);
}
}
}
La forma más eficiente y concisa de lograr esto es agregando una utilidad de iterador. No se moleste en ceder valores. No se moleste en establecer una variable en la directiva ngFor:
function times(max: number) {
return {
[Symbol.iterator]: function* () {
for (let i = 0; i < max; i++, yield) {
}
}
};
}
@Component({
template: ```
<ng-template ngFor [ngForOf]="times(6)">
repeats 6 times!
</ng-template>
```
})
export class MyComponent {
times = times;
}
Declare una variable miembro dentro del componente para hacer referencia a Lodash.
lodash = _;
Luego, en su opinión, puede usar la función de rango . 20 puede ser reemplazado por cualquier variable en su componente.
*ngFor="let number of lodash.range(20)"
Debe decirse que la vinculación a funciones en la vista puede ser costosa, dependiendo de la complejidad de la función que está llamando, ya que Change Detection llamará a la función repetidamente.
No necesita completar la matriz como se sugiere en la mayoría de las respuestas. Si usa index en su ngForbucle, todo lo que necesita crear es una matriz vacía con la longitud correcta:
const elements = Array(n); // n = 20 in your case
y en tu opinión:
<li *ngFor="let element in elements; let i = index">
<span>{{ i }}</span>
</li>
Defina un helperArray y ejecútelo dinámicamente (o estático si lo desea) con la longitud del recuento que desea para crear sus elementos HTML. Por ejemplo, quiero obtener algunos datos del servidor y crear elementos con la longitud de la matriz que se devuelve.
Respuestas:
Puedes usar lo siguiente:
O implementar una tubería personalizada:
fuente
arr=Array;
?Reemplazar
20
con su variablefuente
genera 🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱
fuente
Hay dos problemas con las soluciones recomendadas que utilizan
Arrays
:Parece más eficiente definir a
Pipe
(una vez), devolviendo unIterable
:Ejemplo de uso (renderizado de una cuadrícula con ancho / alto dinámico):
fuente
Puede hacer esto en su HTML:
Y use la variable "número" para indexar.
fuente
20
a una variable miembro .. así que esto no ayudará mucho*ngFor="let number of [0,1,2,3,4,5...,199,200]"
:-DUna solución más simple y reutilizable tal vez sea usar una directiva estructural personalizada como esta.
Y utilícelo así:
fuente
La forma más eficiente y concisa de lograr esto es agregando una utilidad de iterador. No se moleste en ceder valores. No se moleste en establecer una variable en la directiva ngFor:
fuente
Si está utilizando Lodash , puede hacer lo siguiente:
Importe Lodash a su componente.
Declare una variable miembro dentro del componente para hacer referencia a Lodash.
Luego, en su opinión, puede usar la función de rango . 20 puede ser reemplazado por cualquier variable en su componente.
Debe decirse que la vinculación a funciones en la vista puede ser costosa, dependiendo de la complejidad de la función que está llamando, ya que Change Detection llamará a la función repetidamente.
fuente
No necesita completar la matriz como se sugiere en la mayoría de las respuestas. Si usa index en su
ngFor
bucle, todo lo que necesita crear es una matriz vacía con la longitud correcta:y en tu opinión:
fuente
Enfoque más simple:
Defina un helperArray y ejecútelo dinámicamente (o estático si lo desea) con la longitud del recuento que desea para crear sus elementos HTML. Por ejemplo, quiero obtener algunos datos del servidor y crear elementos con la longitud de la matriz que se devuelve.
Luego use helperArray en mi plantilla HTML.
fuente
Aquí hay una versión ligeramente mejorada de la directiva estructural de Ilyass Lamrani que le permite usar el índice en su plantilla:
Uso:
fuente
Sé que pidió específicamente hacerlo usando * ngFor, pero quería compartir la forma en que resolví esto usando una directiva estructural:
Con eso puedes usarlo así:
fuente
Puedes usar esto simplemente:
HTML
TS
fuente