숫자에 따라 ngFor를 사용하여 HTML 요소를 여러 번 반복


답변:


90

다음을 사용할 수 있습니다.

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

1
FillPipe 클래스는 PipeTransform을 구현해야합니다
toumir

1
네 말이 맞아! 더 좋습니다 ;-) 이것을 지적 해 주셔서 감사합니다. 나는 그에 따라 내 대답을 업데이트했습니다 ...
Thierry Templier

6
첫 번째 접근 방식에서 나는 당신이 말하려고했다고 생각합니다 arr=Array;.
Abdulrahman Alsoghayer

3
코드 펜을 만들 수 있습니까? 작동하지 않습니다 : self.parentView.context.arr는 함수가 아닙니다
Toolkit

1
첫 번째 접근에 감사드립니다! 나는 .fill (1)를 사용하고 있지 않다 있고 작동)
gtamborero을

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

20변수로 바꾸기


2
이것은 확실히 좋은 대답입니다
edkeveked

반복은 19이어야합니다. 길이 -1.
Mert Mertce

매우 불편한 문제에 대한 우아한 솔루션입니다. 하지만 많은 요소에 성능 영향이 있다고 생각합니까?
Martin Eckleben

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

생성 🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱🐱


11
정답이되어야합니다 .. 가장 간결합니다!
Mantisimo 19

ERROR RangeError : 잘못된 배열 길이입니다. 그릴 고양이 수가 0 일 때 충돌이 발생합니다.
Tom Bevelander 2019

그 간단한 접근 방식을 정말 좋아합니다!
F. Geißler

51

다음을 사용하는 권장 솔루션에는 두 가지 문제가 있습니다 Arrays.

  1. 낭비입니다. 특히 많은 수의 경우.
  2. 이러한 간단하고 일반적인 작업을 위해 많은 혼란을 초래하는 어딘가에 정의해야합니다.

다음을 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>

26

HTML에서 간단하게 할 수 있습니다.

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

그리고 변수 "number"를 사용하여 색인을 생성합니다.


1
OP는 그가 20멤버 변수에 할당했다고 말했습니다 . 그래서 이것은 많은 도움이되지 않을 것입니다
phil294

200 번 반복하려면 어떻게해야합니까?
Chax

1
@Chax 당신은 할 수 없습니다. :(
Muhammad bin Yusrat 2019

2
@Chax 200의 문제는 무엇입니까? *ngFor="let number of [0,1,2,3,4,5...,199,200]":-D
Stack Underflow

1
@StackUnderflow 슬프게도 나는 캐릭터로 돈을받지 않습니다. 만약 그렇다면, 나는 그것이 달성 할 수있는 유일한 방법이라고 설교 할 것입니다 : P (진지하게하지 마세요;))
Chax

10

더 간단하고 재사용 가능한 솔루션은 이와 같은 맞춤형 구조 지시문을 사용하는 것입니다.

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>

추가 정보를 원하시면 : netbasal.com/...
Ilyass Lamrani

4

이를 달성하는 가장 효율적이고 간결한 방법은 반복자 유틸리티를 추가하는 것입니다. 값을 산출하는 것을 귀찮게하지 마십시오. 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

Lodash 를 사용 하는 경우 다음을 수행 할 수 있습니다.

Lodash 를 구성 요소로 가져 옵니다 .

import * as _ from "lodash";

Lodash를 참조하도록 구성 요소 내에서 멤버 변수를 선언합니다.

lodash = _;

그런 다음보기에서 범위 기능을 사용할 수 있습니다 . 20은 구성 요소의 모든 변수로 바꿀 수 있습니다.

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

Change Detection이 함수를 반복적으로 호출하므로 호출하는 함수의 복잡성에 따라 뷰의 함수에 바인딩하는 데 비용이 많이들 수 있습니다.


1

대부분의 답변에서 제안한대로 배열을 채울 필요가 없습니다. ngFor루프 에서 인덱스를 사용 하는 경우 올바른 길이의 빈 배열 만 만들어야합니다.

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

그리고 당신의 관점에서 :

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

0

더 간단한 접근 방식 :

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

그런 다음 HTML 템플릿에서 helperArray를 사용합니다.

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

0

다음은 템플릿에서 색인을 사용할 수있는 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>

0

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

0

이것을 간단하게 사용할 수 있습니다.

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 {}
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.