Angular 2-Ng 모음 대신 숫자를 사용하는 경우


191

... 예를 들어 ...

<div class="month" *ngFor="#item of myCollection; #i = index">
...
</div>

다음과 같은 일을 할 수 있습니까?

<div class="month" *ngFor="#item of 10; #i = index">
...
</div>

... 다음과 같은 비 우아한 솔루션에 호소하지 않고 :

<div class="month" *ngFor="#item of ['dummy','dummy','dummy','dummy','dummy',
'dummy','dummy','dummy']; #i = index">
...
</div>

?


8
나도 같은 문제가있어. 실제로 화를
내는

1
아마 이것이 도움이 될 수 있습니다 : stackoverflow.com/questions/3895478/…
Pizzicato

답변:


197

구성 요소 내에서 아래 설명과 같이 숫자 배열 (ES6)을 정의 할 수 있습니다.

export class SampleComponent {
  constructor() {
    this.numbers = Array(5).fill().map((x,i)=>i); // [0,1,2,3,4]
    this.numbers = Array(5).fill(4); // [4,4,4,4,4]
  }
}

배열 생성에 대해서는이 링크를 참조하십시오 . JavaScript에서 1..20의 정수 배열을 만드는 가장 좋은 방법 입니다.

그런 다음 다음을 사용하여이 배열을 반복 할 수 있습니다 ngFor.

@Component({
  template: `
    <ul>
      <li *ngFor="let number of numbers">{{number}}</li>
    </ul>
  `
})
export class SampleComponent {
  (...)
}

또는 곧 :

@Component({
  template: `
    <ul>
      <li *ngFor="let number of [0,1,2,3,4]">{{number}}</li>
    </ul>
  `
})
export class SampleComponent {
  (...)
}

5
예, 티에리! 그것은 실제로 당신의 잘못이 아니지만 여전히 같은 맥락에 있습니다 : (아직 우아하지는 않습니다. 그러나 당신은 매우 숙련 된 A2 개발자이기 때문에 더 나은 해결책이 없다고 가정 할 수 있습니다. 슬프습니다!
Marco Jr

실제로 루프 구문의 Angular2에는 아무것도 없습니다. 배열을 구축하기 위해 JavaScript가 제공하는 것을 활용해야합니다. 예를 들면 다음과 같습니다 Array(5).fill(4)만들 수 있습니다[4,4,4,4,4]
티에리 Templier에게

3
추신 : @View 주석이 angular2 베타 10 이상에서 제거되었습니다.
Pardeep Jain

23
사용 Array.fill()각도 2 타이프에하면 다음과 같은 오류가 발생 Supplied parameters do not match any signature of call t arget.Array.prototype.fill의 문서를 확인, 그것은 ... 그것은 한 인수가 필요 말한다 - developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
여호수아 러셀

5
Array(5).fill(1).map((x, i) => i + 1); /*[1,2,3,4,5]*/이것은 TS의 오류를 해결합니다
mshahbazm

90

@OP, 당신은 당신의 "비 우아한"해결책에 몹시 가깝습니다.

어때요?

<div class="month" *ngFor="let item of [].constructor(10); let i = index"> ... </div>

여기에 내가 받고 있어요 Array: 하늘의 배열에서 생성자를 [].constructor하기 때문에, Array템플릿 구문에서 인정 상징이 아니며, 내가 할 너무 게으른 Array=Array또는 counter = Array그의 4 예에서와 @ pardeep - 자이나교와 같은 구성 요소 타이프 라이터이다. 그리고 배열을 생성자 밖으로 가져올 필요가 new없기 때문에 없이 호출합니다 .newArray

Array(30)그리고 new Array(30)동등합니다.

배열은 비어있을 것입니다,하지만 당신은 정말 그냥 사용하기를 원하기 때문에이 문제가되지 않습니다 i에서 ;let i = index루프있다.


12
이것이 가장 좋은 대답입니다.
kagronick

이 솔루션은 변경 감지를 트리거합니다. 새로운 배열로 인해 추측합니다.
Tobias81

1
@ Tobias81, 자세히 설명해 주시겠습니까? 앱이 변경 감지를 실행할 때마다 배열이 다시 작성되므로 * ngFor의 컨텐츠가 다시 그려진다는 말입니까? 확실히 주목할 가치가 있습니다. 실제로 TS에서 배열 필드를 만들어 참조하면 변경 감지가 실행될 때마다 동일하게 해결할 수 있습니다. 그러나 그것은 분명히 원하는 것보다 덜 우아합니다. Thierry Templier에서 선택한 답변의 두 번째 예에 동일한 변경 감지 문제가 있습니까? <li *ngFor="let number of [0,1,2,3,4]">{{number}}</li>
jcairney

이것은이 문제에 대한 최상의 해결책입니다
khush

1
@ Tobias81, 예제 ngFor 지시문의 자식으로 생성하는 구성 요소의 생성자 안에 print 문을 넣어 변경 감지가 ngFor의 내용을 반복적으로 재생하지 않는지 확인했습니다. 모든 변경 감지 반복에서 구성 요소가 재생성되는 것을 보지 못하므로 실제로 문제가 있다고 생각하지 않습니다 (적어도 Angular 8에서는).
jcairney

83

아직 숫자 대신 모음을 사용하는 NgFor에 대한 방법은 없습니다. 현재 * ngFor는 모음을 매개 변수로만 허용하지만 다음 방법으로이를 수행 할 수 있습니다.

파이프 사용

pipe.ts

import {Pipe, PipeTransform} from 'angular2/core';

@Pipe({name: 'demoNumber'})
export class DemoNumber implements PipeTransform {
  transform(value, args:string[]) : any {
    let res = [];
    for (let i = 0; i < value; i++) {
        res.push(i);
      }
      return res;
  }
}


<ul>
  <li>Method First Using PIPE</li>
  <li *ngFor='let key of 5 | demoNumber'>
    {{key}}
  </li>
</ul>

HTML에서 직접 숫자 배열 사용 (보기)

<ul>
  <li>Method Second</li>
  <li *ngFor='let key of  [1,2]'>
    {{key}}
  </li>
</ul>

분할 방법 사용

<ul>
  <li>Method Third</li>
  <li *ngFor='let loop2 of "0123".split("")'>{{loop2}}</li>
</ul>

구성 요소에서 새 배열 만들기 사용

<ul>
  <li>Method Fourth</li>
  <li *ngFor='let loop3 of counter(5) ;let i= index'>{{i}}</li>
</ul>

export class AppComponent {
  demoNumber = 5 ;

  counter = Array;

  numberReturn(length){
    return new Array(length);
  }
}

실무 데모


4
Thierrys 답변과 같이 Array.fill()배열을 생성 하는 방법을 사용할 수도 있습니다 res.push().
Günter Zöchbauer

그래 내가 할 수 있지만 문제가 push있습니까? 나는 두 가지 방법이 모두 정확하지만 여전히 차이점이 있음을 의미합니다. 그들 사이에.
Pardeep Jain

3
아니요, 여전히 좋은 해결책 +1입니다. 난 그냥 찾아 Array.fill()푸시를 사용하여 루프보다 더 우아하고 또한 아마 더 효율적입니다.
Günter Zöchbauer

1
나는 counter = Array매우 똑똑한 이 솔루션을 좋아한다 ;)
Verri

11

구성 요소의 일반 반복을 위해 배열을 할당한다는 아이디어를 견딜 수 없으므로 구조적 지시문을 작성했습니다. 가장 간단한 형태로, 템플릿에서 색인을 사용할 수 없게 만드는 것은 다음과 같습니다.

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({ selector: '[biRepeat]' })
export class RepeatDirective {

  constructor( private templateRef: TemplateRef<any>,
             private viewContainer: ViewContainerRef) { }

  @Input('biRepeat') set count(c:number) {
    this.viewContainer.clear();
    for(var i=0;i<c;i++) {
      this.viewContainer.createEmbeddedView(this.templateRef);
    }
  }
}

http://plnkr.co/edit/bzoNuL7w5Ub0H5MdYyFR?p=preview


나는 배열 접근법이 추악한 것에 동의하지만 이것은 나에게 조기 최적화처럼 보인다.
Aluan Haddad

3
물론 지시어 작성 연습도 있습니다. 다른 한편으로는 파이프보다 길지 않으며, 이는 제 2의 제정신 접근법입니다.
pdudits

좋은 지적입니다. 커스텀 구조적 지시문의 개념으로 당신을 구할 기회가 많지 않습니다.
Aluan Haddad

멋진 하나 @ pdudits-여전히 최신 버전에서 작동 : plnkr.co/edit/8wJtkpzre3cBNokHcDL7?p=preview [ plnkr 을 업데이트하여 주시기 바랍니다]
AT

5

Angular 5.2.6 및 TypeScript 2.6.2를 사용하여 다음과 같이 해결했습니다.

class Range implements Iterable<number> {
    constructor(
        public readonly low: number,
        public readonly high: number,
        public readonly step: number = 1
    ) {
    }

    *[Symbol.iterator]() {
        for (let x = this.low; x <= this.high; x += this.step) {
            yield x;
        }
    }
}

function range(low: number, high: number) {
    return new Range(low, high);
}

다음과 같은 컴포넌트에서 사용할 수 있습니다.

@Component({
    template: `<div *ngFor="let i of r">{{ i }}</div>`
})
class RangeTestComponent {
    public r = range(10, 20);
}

간결성을 위해 오류 검사 및 어설 션이 생략되었습니다 (예 : 단계가 음수 인 경우 발생).


2
현재 HTML에서 어떤 방법이있다 있습니까 <div *ngfor="let i of 4, i++"></div>있을 수 있습니다
Nithila Shanmugananthan가

5

당신은 또한 그렇게 사용할 수 있습니다

export class SampleComponent {
   numbers:Array<any> = [];
   constructor() {
      this.numbers = Array.from({length:10},(v,k)=>k+1);
   }
}

HTML

<p *ngFor="let i of numbers">
   {{i}}
</p>

4

lodash를 사용할 수 있습니다 :

@Component({
  selector: 'board',
  template: `
<div *ngFor="let i of range">
{{i}}
</div>
`,
  styleUrls: ['./board.component.css']
})
export class AppComponent implements OnInit {
  range = _.range(8);
}

코드를 테스트하지 않았지만 작동해야합니다.


현재 HTML에서 어떤 방법이있다 있습니까 <div *ngfor="let i of 4, i++"></div>있을 수 있습니다
Nithila Shanmugananthan가

i코드 가 필요 하거나 색인을 작성하면 할 수 있습니다*ngFor="let i of range; let i = index"
Alex Po

3

이것은 또한 다음과 같이 달성 될 수 있습니다 :

HTML :

<div *ngFor="let item of fakeArray(10)">
     ...
</div>

타자기 :

fakeArray(length: number): Array<any> {
  if (length >= 0) {
    return new Array(length);
  }
}

실무 데모


2

인수없이 fill () 메소드 (허용 된 답변에 언급 됨)에 오류가 발생하므로 다음과 같이 제안 할 것입니다 (Angular 7.0.4, Typescript 3.1.6).

<div class="month" *ngFor="let item of items">
...
</div>

구성 요소 코드에서 :

this.items = Array.from({length: 10}, (v, k) => k + 1);

1
<div *ngFor="let number of [].constructor(myCollection)">
    <div>
        Hello World
    </div>
</div>

이것은 myCollection에서 여러 번 반복하는 훌륭하고 빠른 방법입니다.

따라서 myCollection이 5이면 Hello World가 5 번 반복됩니다.


1

인덱스와 함께 사용자 지정 구조 지시문 사용 :

Angular 문서에 따르면 :

createEmbeddedView 내장 된 뷰를 인스턴스화하여이 컨테이너에 삽입합니다.

abstract createEmbeddedView(templateRef: TemplateRef, context?: C, index?: number): EmbeddedViewRef.

Param          Type           Description
templateRef    TemplateRef    the HTML template that defines the view.
context        C              optional. Default is undefined.
index          number         the 0-based index at which to insert the new view into this container. If not specified, appends the new view as the last entry.

angular가 createEmbeddedView를 호출하여 템플릿을 만들면 내부에서 사용될 컨텍스트를 전달할 수도 있습니다 ng-template.

컨텍스트 선택적 매개 변수를 사용하면 컴포넌트에서이를 사용하여 * ngFor에서와 같이 템플리트 내에서 추출 할 수 있습니다.

app.component.html :

<p *for="number; let i=index; let c=length; let f=first; let l=last; let e=even; let o=odd">
  item : {{i}} / {{c}}
  <b>
    {{f ? "First,": ""}}
    {{l? "Last,": ""}}
    {{e? "Even." : ""}}
    {{o? "Odd." : ""}}
  </b>
</p>

for.directive.ts :

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

class Context {
  constructor(public index: number, public length: number) { }
  get even(): boolean { return this.index % 2 === 0; }
  get odd(): boolean { return this.index % 2 === 1; }
  get first(): boolean { return this.index === 0; }
  get last(): boolean { return this.index === this.length - 1; }
}

@Directive({
  selector: '[for]'
})
export class ForDirective {
  constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }

  @Input('for') set loop(num: number) {
    for (var i = 0; i < num; i++)
      this.viewContainer.createEmbeddedView(this.templateRef, new Context(i, num));
  }
}

0

버튼을 클릭 한 후 배열의 크기를 동적으로 늘리려면 첨부 된 내 동적 솔루션을 찾으십시오 (이것이 내가이 질문에 도달 한 방법입니다).

필요한 변수 할당 :

  array = [1];
  arraySize: number;

배열에 요소를 추가하는 함수를 선언하십시오.

increaseArrayElement() {
   this.arraySize = this.array[this.array.length - 1 ];
   this.arraySize += 1;
   this.array.push(this.arraySize);
   console.log(this.arraySize);
}

html로 함수를 호출하십시오.

  <button md-button (click)="increaseArrayElement()" >
      Add element to array
  </button>

ngFor를 사용하여 배열을 반복하십시오.

<div *ngFor="let i of array" >
  iterateThroughArray: {{ i }}
</div>

현재 HTML에서 어떤 방법이있다 있습니까 <div *ngfor="let i of 4, i++"></div>있을 수 있습니다
Nithila Shanmugananthan가

배열을 반복해야합니다. 당신이 스칼라을해야하는 경우에는 적당한 크기와 배열을 반복하고 추가로 스칼라를 인스턴스화 할 수 있습니다 : * ngFor = "배열의 항목을하자, 나는 인덱스 =하자"
월 클레멘스 Stoffregen을

0

내가 시도한 가장 간단한 방법

구성 요소 파일에 배열을 만들 수도 있고 배열로 반환하여 * ngFor 지시문으로 배열을 호출 할 수도 있습니다.

이 같은 ....

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-morning',
  templateUrl: './morning.component.html',
  styleUrls: ['./morning.component.css']
})
export class MorningComponent implements OnInit {

  arr = [];
  i: number = 0;
  arra() {
    for (this.i = 0; this.i < 20; this.i++) {
      this.arr[this.i]=this.i;
    }
    return this.arr;
  }

  constructor() { }

  ngOnInit() {
  }

}

이 기능은 HTML 템플릿 파일에서 사용할 수 있습니다

<p *ngFor="let a of arra(); let i= index">
value:{{a}} position:{{i}}
</p>

2
현재 HTML에서 어떤 방법이있다 있습니까 <div *ngfor="let i of 4, i++"></div>있을 수 있습니다
Nithila Shanmugananthan가

0

내 해결책 :

export class DashboardManagementComponent implements OnInit {
  _cols = 5;
  _rows = 10;
  constructor() { }

  ngOnInit() {
  }

  get cols() {
    return Array(this._cols).fill(null).map((el, index) => index);
  }
  get rows() {
    return Array(this._rows).fill(null).map((el, index) => index);
  }

html로 :

<div class="charts-setup">
  <div class="col" *ngFor="let col of cols; let colIdx = index">
    <div class="row" *ngFor="let row of rows; let rowIdx = index">
      Col: {{colIdx}}, row: {{rowIdx}}
    </div>
  </div>
</div>

이것은 모든 얻을 때마다 새로운 배열을 만듭니다. 오버 헤드를 만들 수 있음
Remco Vlierman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.