Wie kann ich *ngFor
ein HTML-Element mehrmals wiederholen?
Zum Beispiel: Wenn ich eine Mitgliedsvariable 20 zugewiesen habe. Wie verwende ich die Direktive * ngFor, um ein Div 20 Mal wiederholen zu lassen?
Wie kann ich *ngFor
ein HTML-Element mehrmals wiederholen?
Zum Beispiel: Wenn ich eine Mitgliedsvariable 20 zugewiesen habe. Wie verwende ich die Direktive * ngFor, um ein Div 20 Mal wiederholen zu lassen?
Antworten:
Sie könnten Folgendes verwenden:
@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;
}
Oder implementieren Sie eine benutzerdefinierte Pipe:
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;
}
arr=Array;
?
<div *ngFor="let dummy of ' '.repeat(20).split(''), let x = index">
Ersetzen Sie 20
durch Ihre Variable
<ng-container *ngFor="let i of [].constructor(20)">🐱</ng-container>
erzeugt 🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱
Es gibt zwei Probleme mit den empfohlenen Lösungen Arrays
:
Es scheint effizienter zu sein, ein Pipe
(einmaliges) zu definieren und ein 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;
}
}
Anwendungsbeispiel (Rendern eines Rasters mit dynamischer Breite / Höhe):
<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>
Sie können dies einfach in Ihrem HTML tun:
*ngFor="let number of [0,1,2,3,4,5...,18,19]"
Und verwenden Sie die Variable "Nummer" zum Indizieren.
20
habe einer Mitgliedsvariablen zugewiesen . Das wird also nicht viel helfen
*ngFor="let number of [0,1,2,3,4,5...,199,200]"
:-D
Eine einfachere und wiederverwendbare Lösung ist möglicherweise die Verwendung einer solchen benutzerdefinierten Strukturanweisung.
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);
}
}
}
Und benutze es so:
<span *appTimes="3" class="fa fa-star"></span>
Der effizienteste und präziseste Weg, dies zu erreichen, ist das Hinzufügen eines Iterator-Dienstprogramms. Machen Sie sich nicht die Mühe, Werte zu liefern. Machen Sie sich nicht die Mühe, eine Variable in der ngFor-Direktive festzulegen:
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;
}
Wenn Sie Lodash verwenden , können Sie Folgendes tun:
Importieren Sie Lodash in Ihre Komponente.
import * as _ from "lodash";
Deklarieren Sie eine Mitgliedsvariable innerhalb der Komponente, um auf Lodash zu verweisen.
lodash = _;
In Ihrer Ansicht können Sie dann die Bereichsfunktion verwenden . 20 kann durch eine beliebige Variable in Ihrer Komponente ersetzt werden.
*ngFor="let number of lodash.range(20)"
Es muss gesagt werden, dass das Binden an Funktionen in der Ansicht abhängig von der Komplexität der Funktion, die Sie aufrufen, kostspielig sein kann, da die Änderungserkennung die Funktion wiederholt aufruft.
Sie müssen das Array nicht wie in den meisten Antworten vorgeschlagen füllen. Wenn Sie in Ihrer ngFor
Schleife einen Index verwenden , müssen Sie lediglich ein leeres Array mit der richtigen Länge erstellen:
const elements = Array(n); // n = 20 in your case
und aus Ihrer Sicht:
<li *ngFor="let element in elements; let i = index">
<span>{{ i }}</span>
</li>
Einfacherer Ansatz:
Definieren Sie ein helperArray und instanziieren Sie es dynamisch (oder statisch, wenn Sie möchten) mit der Länge der Anzahl, mit der Sie Ihre HTML-Elemente erstellen möchten. Zum Beispiel möchte ich einige Daten vom Server abrufen und Elemente mit der Länge des zurückgegebenen Arrays erstellen.
export class AppComponent {
helperArray: Array<any>;
constructor(private ss: StatusService) {
}
ngOnInit(): void {
this.ss.getStatusData().subscribe((status: Status[]) => {
this.helperArray = new Array(status.length);
});
}
}
Verwenden Sie dann das helperArray in meiner HTML-Vorlage.
<div class="content-container" *ngFor="let i of helperArray">
<general-information></general-information>
<textfields></textfields>
</div>
Hier ist eine leicht verbesserte Version der Strukturanweisung von Ilyass Lamrani, mit der Sie den Index in Ihrer Vorlage verwenden können:
@Directive({
selector: '[appRepeatOf]'
})
export class RepeatDirective {
constructor(private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) {
}
@Input()
set appRepeatOf(times: number) {
const initialLength = this.viewContainer.length;
const diff = times - initialLength;
if (diff > 0) {
for (let i = initialLength; i < initialLength + diff; i++) {
this.viewContainer.createEmbeddedView(this.templateRef, {
$implicit: i
});
}
} else {
for (let i = initialLength - 1; i >= initialLength + diff ; i--) {
this.viewContainer.remove(i);
}
}
}
Verwendung:
<li *appRepeat="let i of myNumberProperty">
Index: {{i}}
</li>
Ich weiß, dass Sie ausdrücklich darum gebeten haben, dies mit * ngFor zu tun, aber ich wollte mitteilen, wie ich dies mithilfe einer strukturellen Richtlinie gelöst habe:
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);
}
}
}
Damit können Sie es einfach so verwenden:
<div *appRepeat="15">
Testing
</div>
Sie können dies einfach verwenden:
HTML
<div *ngFor="let i of Count">
TS
export class Component implements OnInit {
Count = [];
constructor() {
this.Count.length = 10; //you can give any number
}
ngOnInit(): void {}
}