@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;
}
Ou implémentez un tube personnalisé:
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;
}
Cela devrait être la bonne réponse. C'est de loin la plus concise!
Mantisimo
ERROR RangeError: longueur de tableau non valide. Cela plantera lorsque le nombre de chats à dessiner sera nul.
Tom Bevelander
J'aime vraiment cette approche simple!
F. Geißler
51
Il y a deux problèmes avec les solutions recommandées en utilisant Arrays:
C'est du gaspillage. En particulier pour les grands nombres.
Vous devez les définir quelque part, ce qui entraîne beaucoup d'encombrement pour une opération aussi simple et courante.
Il semble plus efficace de définir un Pipe(une fois), en retournant 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;
}
}
Exemple d'utilisation (rendu d'une grille avec largeur / hauteur dynamique):
<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 dit qu'il a assigné 20à une variable membre .. donc cela n'aidera pas beaucoup
phil294
Et si je veux répéter 200 fois?
Chax
1
@Chax Vous ne pouvez pas. :(
Muhammad bin Yusrat
2
@Chax Quel est le problème avec 200? *ngFor="let number of [0,1,2,3,4,5...,199,200]":-D
Stack Underflow
1
@StackUnderflow Malheureusement, je ne suis pas payé par les personnages. Si c'était le cas, je prêcherais que c'est le seul moyen d'y parvenir: P (sérieusement, ne le faites pas;))
Chax
10
Une solution plus simple et réutilisable peut-être d'utiliser une directive structurelle personnalisée comme celle-ci.
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);
}
}
}
Le moyen le plus efficace et le plus concis d'y parvenir est d'ajouter un utilitaire d'itération. Ne vous embêtez pas à donner des valeurs. Ne vous embêtez pas à définir une variable dans la directive 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;
}
Déclarez une variable membre dans le composant pour référencer Lodash.
lodash = _;
Ensuite, dans votre vue, vous pouvez utiliser la fonction de plage . 20 peut être remplacé par n'importe quelle variable de votre composant.
*ngFor="let number of lodash.range(20)"
Il faut dire que la liaison à des fonctions dans la vue peut être coûteuse, selon la complexité de la fonction que vous appelez, car la détection de changement appellera la fonction à plusieurs reprises.
Vous n'avez pas besoin de remplir le tableau comme suggéré dans la plupart des réponses. Si vous utilisez index dans votre ngForboucle, il vous suffit de créer un tableau vide avec la longueur correcte:
const elements = Array(n); // n = 20 in your case
et à votre avis:
<li *ngFor="let element in elements; let i = index">
<span>{{ i }}</span>
</li>
Définissez un helperArray et instanciez-le dynamiquement (ou statique si vous le souhaitez) avec la longueur du nombre que vous souhaitez créer vos éléments HTML. Par exemple, je souhaite obtenir des données du serveur et créer des éléments avec la longueur du tableau renvoyé.
Je sais que vous avez spécifiquement demandé de le faire en utilisant * ngFor, mais je voulais partager la façon dont j'ai résolu cela en utilisant une directive structurelle:
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({ selector: '[appRepeat]' })
export class RepeatDirective {
constructor(private templateRef: TemplateRef<any>, private viewContainerRef: ViewContainerRef) {
}
@Input() set appRepeat(loops: number) {
for (let index = 0; index < loops; ++index) {
this.viewContainerRef.createEmbeddedView(this.templateRef);
}
}
}
Réponses:
Vous pouvez utiliser les éléments suivants:
Ou implémentez un tube personnalisé:
la source
arr=Array;
?Remplacez
20
par votre variablela source
génère 🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱
la source
Il y a deux problèmes avec les solutions recommandées en utilisant
Arrays
:Il semble plus efficace de définir un
Pipe
(une fois), en retournant unIterable
:Exemple d'utilisation (rendu d'une grille avec largeur / hauteur dynamique):
la source
Vous pouvez simplement le faire dans votre HTML:
Et utilisez la variable "nombre" pour indexer.
la source
20
à une variable membre .. donc cela n'aidera pas beaucoup*ngFor="let number of [0,1,2,3,4,5...,199,200]"
:-DUne solution plus simple et réutilisable peut-être d'utiliser une directive structurelle personnalisée comme celle-ci.
Et utilisez-le comme ceci:
la source
Le moyen le plus efficace et le plus concis d'y parvenir est d'ajouter un utilitaire d'itération. Ne vous embêtez pas à donner des valeurs. Ne vous embêtez pas à définir une variable dans la directive ngFor:
la source
Si vous utilisez Lodash , vous pouvez effectuer les opérations suivantes:
Importez Lodash dans votre composant.
Déclarez une variable membre dans le composant pour référencer Lodash.
Ensuite, dans votre vue, vous pouvez utiliser la fonction de plage . 20 peut être remplacé par n'importe quelle variable de votre composant.
Il faut dire que la liaison à des fonctions dans la vue peut être coûteuse, selon la complexité de la fonction que vous appelez, car la détection de changement appellera la fonction à plusieurs reprises.
la source
Vous n'avez pas besoin de remplir le tableau comme suggéré dans la plupart des réponses. Si vous utilisez index dans votre
ngFor
boucle, il vous suffit de créer un tableau vide avec la longueur correcte:et à votre avis:
la source
Approche plus simple:
Définissez un helperArray et instanciez-le dynamiquement (ou statique si vous le souhaitez) avec la longueur du nombre que vous souhaitez créer vos éléments HTML. Par exemple, je souhaite obtenir des données du serveur et créer des éléments avec la longueur du tableau renvoyé.
Ensuite, utilisez le helperArray dans mon modèle HTML.
la source
Voici une version légèrement améliorée de la directive structurelle d'Ilyass Lamrani qui vous permet d'utiliser l'index dans votre modèle:
Usage:
la source
Je sais que vous avez spécifiquement demandé de le faire en utilisant * ngFor, mais je voulais partager la façon dont j'ai résolu cela en utilisant une directive structurelle:
Avec cela, vous pouvez l'utiliser comme ceci:
la source
Vous pouvez utiliser ceci simplement:
HTML
TS
la source