Як я можу *ngFor
повторювати HTML-елемент кілька разів?
Наприклад: Якщо у мене змінна члена присвоюється 20. Як я можу використовувати директиву * ngFor, щоб зробити повтор діва 20 разів?
Як я можу *ngFor
повторювати HTML-елемент кілька разів?
Наприклад: Якщо у мене змінна члена присвоюється 20. Як я можу використовувати директиву * ngFor, щоб зробити повтор діва 20 разів?
Відповіді:
Ви можете використовувати наступне:
@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;
}
Або реалізуйте спеціальну трубу:
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">
Замініть 20
свою змінну
<ng-container *ngFor="let i of [].constructor(20)">🐱</ng-container>
породжує 🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱
Існує дві проблеми з рекомендованими рішеннями із використанням Arrays
:
Здається ефективнішим визначити Pipe
(раз), повертаючи 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;
}
}
Приклад використання (надання сітки з динамічною шириною / висотою):
<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>
Ви можете просто зробити це у своєму HTML:
*ngFor="let number of [0,1,2,3,4,5...,18,19]"
І використовуйте змінну "число" для індексації.
20
змінну члена. Тому це не дуже допоможе
*ngFor="let number of [0,1,2,3,4,5...,199,200]"
:-D
Більш просте і багаторазове рішення, можливо, використовувати спеціальну структурну директиву, як це.
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);
}
}
}
І використовуйте його так:
<span *appTimes="3" class="fa fa-star"></span>
Найбільш ефективний і стислий спосіб досягти цього - додавання утиліти ітератора. Не турбуйте урожайні значення. Не турбуйтеся про встановлення змінної в директиві 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;
}
Якщо ви використовуєте Lodash , ви можете зробити наступне:
Імпортуйте Lodash у свій компонент.
import * as _ from "lodash";
Оголосити змінну члена всередині компонента для посилання на Lodash.
lodash = _;
Тоді, на ваш погляд, ви можете використовувати функцію діапазону . 20 можна замінити будь-якою змінною у вашому компоненті.
*ngFor="let number of lodash.range(20)"
Потрібно сказати, що прив'язка до функцій у представленні може бути дорогою, залежно від складності функції, яку ви викликаєте, оскільки функція виявлення змін буде викликати функцію повторно.
Вам не потрібно заповнювати масив, як запропоновано в більшості відповідей. Якщо ви використовуєте індекс у своєму ngFor
циклі, все, що вам потрібно створити, це порожній масив правильної довжини:
const elements = Array(n); // n = 20 in your case
і на ваш погляд:
<li *ngFor="let element in elements; let i = index">
<span>{{ i }}</span>
</li>
Простіший підхід:
Визначте helperArray та інстанціюйте його динамічно (або статично, якщо ви хочете) з довжиною підрахунку, який ви хочете створити ваші HTML елементи. Наприклад, я хочу отримати деякі дані з сервера та створити елементи з довжиною масиву, який повертається.
export class AppComponent {
helperArray: Array<any>;
constructor(private ss: StatusService) {
}
ngOnInit(): void {
this.ss.getStatusData().subscribe((status: Status[]) => {
this.helperArray = new Array(status.length);
});
}
}
Потім використовуйте helperArray в моєму HTML-шаблоні.
<div class="content-container" *ngFor="let i of helperArray">
<general-information></general-information>
<textfields></textfields>
</div>
Ось дещо вдосконалена версія структурної директиви Ilyass Lamrani, яка дозволяє використовувати індекс у вашому шаблоні:
@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);
}
}
}
Використання:
<li *appRepeat="let i of myNumberProperty">
Index: {{i}}
</li>
Я знаю, що ви спеціально попросили це зробити за допомогою * ngFor, але я хотів поділитися способом вирішення цього питання за допомогою структурної директиви:
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);
}
}
}
З цим ви можете використовувати це саме так:
<div *appRepeat="15">
Testing
</div>
Ви можете використовувати це просто:
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 {}
}