ฉันจะใช้*ngFor
เพื่อทำองค์ประกอบ HTML ซ้ำหลาย ๆ ครั้งได้อย่างไร
ตัวอย่างเช่น: ถ้าฉันมีตัวแปรสมาชิกที่กำหนดให้เป็น 20 ฉันจะใช้คำสั่ง * ngFor เพื่อสร้าง div ซ้ำ 20 ครั้งได้อย่างไร
ฉันจะใช้*ngFor
เพื่อทำองค์ประกอบ HTML ซ้ำหลาย ๆ ครั้งได้อย่างไร
ตัวอย่างเช่น: ถ้าฉันมีตัวแปรสมาชิกที่กำหนดให้เป็น 20 ฉันจะใช้คำสั่ง * ngFor เพื่อสร้าง div ซ้ำ 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;
?
<ng-container *ngFor="let i of [].constructor(20)">🐱</ng-container>
สร้าง🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱
<div *ngFor="let dummy of ' '.repeat(20).split(''), let x = index">
แทนที่20
ด้วยตัวแปรของคุณ
มีปัญหาสองประการในแนวทางแก้ไขที่แนะนำโดยใช้Arrays
:
ดูเหมือนว่าจะมีประสิทธิภาพมากขึ้นในการกำหนด a 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]"
และใช้ตัวแปร "number" เพื่อจัดทำดัชนี
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>
คุณสามารถใช้สิ่งนี้ได้ง่ายๆ:
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 {}
}
แนวทางที่ง่ายกว่า:
กำหนด 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>