Ulangi elemen HTML beberapa kali menggunakan ngFor berdasarkan angka


Jawaban:


90

Anda bisa menggunakan yang berikut ini:

@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;
}

Atau terapkan pipa khusus:

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;
}

1
kelas FillPipe harus mengimplementasikan PipeTransform
toumir

1
Ya kau benar! Lebih baik ;-) Terima kasih telah menunjukkan hal ini. Saya memperbarui jawaban saya sesuai ...
Thierry Templier

6
Dalam pendekatan pertama, saya pikir Anda bermaksud mengatakan arr=Array;?
Abdulrahman Alsoghayer

3
bisakah kamu membuat codepen? tidak berfungsi: self.parentView.context.arr bukan fungsi
Toolkit

1
Terima kasih untuk pendekatan pertama! Saya tidak menggunakan .fill (1) dan berfungsi;)
gtamborero

76
<div *ngFor="let dummy of ' '.repeat(20).split(''), let x = index">

Ganti 20dengan variabel Anda


2
Ini jelas merupakan jawaban yang bagus
edkeveked

ulangi harus 19; panjang-1.
Mert Mertce

Solusi elegan untuk masalah yang sangat tidak nyaman. Tapi saya kira itu memiliki dampak kinerja untuk sejumlah besar elemen?
Martin Eckleben

76
<ng-container *ngFor="let i of [].constructor(20)">🐱</ng-container>

menghasilkan 🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱


11
Ini harus menjadi jawaban yang benar .. Sejauh ini yang paling ringkas!
Mantisimo

ERROR RangeError: Panjang array tidak valid. Ini akan macet ketika jumlah kucing yang akan digambar adalah nol.
Tom Bevelander

Benar-benar menyukai pendekatan sederhana itu!
F. Geißler

51

Ada dua masalah dengan solusi yang disarankan menggunakan Arrays:

  1. Itu boros. Khususnya untuk jumlah yang besar.
  2. Anda harus mendefinisikannya di suatu tempat yang menghasilkan banyak kekacauan untuk operasi yang sederhana dan umum seperti itu.

Tampaknya lebih efisien untuk mendefinisikan Pipe(sekali), mengembalikan 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;
  }
}

Contoh penggunaan (menampilkan petak dengan lebar / tinggi dinamis):

<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>

26

Anda dapat dengan mudah melakukan ini di HTML Anda:

*ngFor="let number of [0,1,2,3,4,5...,18,19]"

Dan gunakan variabel "angka" untuk mengindeks.


1
OP mengatakan dia ditugaskan 20ke variabel anggota .. jadi ini tidak akan banyak membantu
phil294

Bagaimana jika saya ingin mengulang 200 kali?
Chax

1
@Chax Anda tidak bisa. :(
Muhammad bin Yusrat

2
@Chax Apa yang salah dengan 200? *ngFor="let number of [0,1,2,3,4,5...,199,200]":-D
Stack Underflow

1
@StackUnderflow Sayangnya saya tidak dibayar oleh karakter. Jika ya, saya akan berkhotbah bahwa itu adalah satu-satunya cara untuk mencapai itu: P (serius saja jangan;))
Chax

10

Solusi yang lebih sederhana dan dapat digunakan kembali mungkin menggunakan arahan struktural kustom seperti ini.

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);
    }
  }

}

Dan gunakan seperti ini:

<span *appTimes="3" class="fa fa-star"></span>

untuk info lebih lanjut: netbasal.com/…
Ilyass Lamrani

4

Cara paling efisien dan ringkas untuk mencapai ini adalah dengan menambahkan utilitas iterator. Jangan repot-repot memberikan nilai. Jangan repot-repot menyetel variabel di direktif 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;
}

1

Jika Anda menggunakan Lodash , Anda dapat melakukan hal berikut:

Impor Lodash ke dalam komponen Anda.

import * as _ from "lodash";

Deklarasikan variabel anggota dalam komponen untuk mereferensikan Lodash.

lodash = _;

Kemudian dalam pandangan Anda, Anda dapat menggunakan fungsi jangkauan . 20 dapat diganti dengan variabel apa pun di komponen Anda.

*ngFor="let number of lodash.range(20)"

Harus dikatakan bahwa mengikat fungsi dalam tampilan mungkin mahal, tergantung pada kompleksitas fungsi yang Anda panggil karena Deteksi Perubahan akan memanggil fungsi tersebut berulang kali.


1

Anda tidak perlu mengisi larik seperti yang disarankan di sebagian besar jawaban. Jika Anda menggunakan index dalam ngForloop Anda, yang perlu Anda buat hanyalah array kosong dengan panjang yang benar:

const elements = Array(n); // n = 20 in your case

dan menurut pandangan Anda:

<li *ngFor="let element in elements; let i = index">
  <span>{{ i }}</span>
</li>

0

Pendekatan yang lebih sederhana:

Definisikan helperArray dan buat instance secara dinamis (atau statis jika Anda mau) dengan panjang hitungan yang Anda inginkan untuk membuat elemen HTML. Misalnya, saya ingin mendapatkan beberapa data dari server dan membuat elemen dengan panjang array yang dikembalikan.

export class AppComponent {
  helperArray: Array<any>;

  constructor(private ss: StatusService) {
  }

  ngOnInit(): void {
    this.ss.getStatusData().subscribe((status: Status[]) => {
      this.helperArray = new Array(status.length);
    });
  }
}

Kemudian gunakan helperArray di template HTML saya.

<div class="content-container" *ngFor="let i of helperArray">
  <general-information></general-information>
  <textfields></textfields>
</div>

0

Berikut adalah versi yang sedikit lebih baik dari petunjuk struktural Ilyass Lamrani yang memungkinkan Anda menggunakan indeks di templat Anda:

@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);
    }
  }

}

Pemakaian:

<li *appRepeat="let i of myNumberProperty">
    Index: {{i}}
</li>

0

Saya tahu Anda secara khusus meminta untuk melakukannya menggunakan * ngFor, tetapi saya ingin berbagi cara saya menyelesaikan ini menggunakan arahan struktural:

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);
    }
  }
}

Dengan itu Anda bisa menggunakannya seperti ini:

<div *appRepeat="15">
  Testing
</div>

0

Anda dapat menggunakan ini dengan mudah:

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 {}
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.