Bir sayıya bağlı olarak ngFor kullanarak HTML öğesini birkaç kez tekrarlayın


Yanıtlar:


91

Aşağıdakileri kullanabilirsiniz:

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

Veya özel bir boru uygulayın:

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
FillPipe sınıfı PipeTransform'u uygulamalıdır
toumir

1
Evet haklısın! Daha iyi ;-) Bunu işaret ettiğiniz için teşekkürler. Cevabımı buna göre güncelledim ...
Thierry Templier

6
İlk yaklaşımda, demek istediğini düşünüyorum arr=Array;?
Abdulrahman Alsoghayer

3
codepen yapabilir misin? çalışmıyor: self.parentView.context.arr bir işlev değil
Araç Seti

1
İlk yaklaşım için teşekkürler! .Fill (1) 'i kullanmıyorum ve çalışıyor;)
gtamborero

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

üretir 🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱


11
Doğru cevap bu olmalı .. Açık ara en özlü!
Mantisimo

ERROR RangeError: Geçersiz dizi uzunluğu. Bu, çizilecek kedi sayısı sıfır olduğunda çökecektir.
Tom Bevelander

Gerçekten bu basit yaklaşım gibi!
F.Geißler

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

20Değişkeninizle değiştirin


2
Bu kesinlikle harika bir cevap
2018

tekrar 19 olmalıdır; uzunluk-1.
Mert Mertce

Oldukça rahatsız edici bir sorun için zarif çözüm. Ama sanırım çok sayıda öğe için performans etkisi var?
Martin Eckleben

51

Önerilen çözümlerin kullanılmasıyla ilgili iki sorun vardır Arrays:

  1. Bu savurgan. Özellikle büyük sayılar için.
  2. Bunları bir yerde tanımlamalısınız, bu da böylesine basit ve yaygın bir işlem için çok fazla dağınıklığa neden olur.

Bir Pipe(bir kez) tanımlamak daha verimli görünüyor ve şunu döndürüyor 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;
  }
}

Kullanım örneği (dinamik genişlik / yüksekliğe sahip bir ızgara oluşturma):

<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

Bunu HTML'nizde basitçe yapabilirsiniz:

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

Ve endekslemek için "sayı" değişkenini kullanın.


1
OP 20bir üye değişkeni atadığını söyledi .. bu yüzden bu pek yardımcı olmayacak
phil294

Ya 200 kez yinelemek istersem?
Chax

1
@Chax Yapamazsın. :(
Muhammed bin Yusrat

2
@Chax 200'ün nesi var? *ngFor="let number of [0,1,2,3,4,5...,199,200]":-D
Stack

1
@StackUnderflow Ne yazık ki bana karakterler tarafından ödeme yapılmıyor. Öyle olsaydım, şuna ulaşmanın tek yolunun bu olduğunu vaaz ederdim: P (cidden, sadece yapma;))
Chax

10

Daha basit ve yeniden kullanılabilir bir çözüm, bunun gibi özel yapısal yönergeleri kullanabilir.

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

}

Ve bunu şu şekilde kullanın:

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

daha fazla bilgi için: netbasal.com/…
Ilyass Lamrani

4

Bunu başarmanın en verimli ve özlü yolu, bir yineleyici yardımcı programı eklemektir. Verici değerler ile uğraşmayın. NgFor yönergesinde bir değişken belirlemeye zahmet etmeyin:

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

Lodash kullanıyorsanız , aşağıdakileri yapabilirsiniz:

Lodash'ı bileşeninize aktarın .

import * as _ from "lodash";

Lodash'a başvurmak için bileşen içindeki bir üye değişkeni bildirin.

lodash = _;

Ardından, sizin görüşünüzde aralık işlevini kullanabilirsiniz . 20, bileşeninizdeki herhangi bir değişken ile değiştirilebilir.

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

Görünümdeki işlevlere bağlanmanın, aradığınız işlevin karmaşıklığına bağlı olarak maliyetli olabileceği söylenmelidir, çünkü Değişiklik Algılama işlevi tekrar tekrar çağıracaktır.


1

Çoğu cevapta önerildiği gibi diziyi doldurmanıza gerek yoktur. Döngünüzde dizin kullanırsanız ngFor, oluşturmanız gereken tek şey doğru uzunlukta boş bir dizidir:

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

ve size göre:

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

0

Daha basit yaklaşım:

Bir helperArray tanımlayın ve HTML öğelerinizi oluşturmak istediğiniz sayının uzunluğuyla dinamik olarak (veya isterseniz statik olarak) somutlaştırın. Örneğin, sunucudan bazı veriler almak ve döndürülen dizinin uzunluğuna sahip öğeler oluşturmak istiyorum.

export class AppComponent {
  helperArray: Array<any>;

  constructor(private ss: StatusService) {
  }

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

Ardından, HTML şablonumdaki helperArray'i kullanın.

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

0

Şablonunuzda dizini kullanmanıza izin veren Ilyass Lamrani'nin yapısal yönergesinin biraz geliştirilmiş bir versiyonu:

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

}

Kullanım:

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

0

Bunu özellikle * ngFor kullanarak yapmak istediğini biliyorum, ancak yapısal bir direktif kullanarak bunu çözme şeklimle paylaşmak istedim:

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

Bununla aynen şu şekilde kullanabilirsiniz:

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

0

Bunu basitçe kullanabilirsiniz:

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 {}
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.