Angular 2 - NgДля использования чисел вместо коллекций
... например...
<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>
?
Ответы
Ответ 1
Внутри вашего компонента вы можете определить массив числа (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]
}
}
См. эту ссылку для создания массива: Tersest способ создания массива целых чисел от 1..20 в JavaScript.
Затем вы можете перебрать этот массив с помощью 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 {
(...)
}
Ответ 2
Нет, пока нет никакого способа для NgFor использовать числа вместо коллекций,
На данный момент * ngFor принимает коллекцию только как параметр, но вы можете сделать это следующими способами:
Использование pipes
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>
Использование метода Split
<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);
}
}
Ответ 3
@OP, вы были очень близки со своим "не элегантным" решением.
Как насчет:
<div class="month" *ngFor="let item of [].constructor(10); let я = index">... </div>
Здесь я получаю конструктор Array
из пустого массива: [].constructor
, потому что Array
не является распознанным символом в синтаксисе шаблона, и мне лень делать Array=Array
или counter = Array
в [].constructor
компонента как @pardeep-jain сделал в своем 4-м примере. И я называю это без new
потому что new
не нужно для получения массива из конструктора Array
.
Array(30)
и new Array(30)
эквивалентны.
Массив будет пустым, но это не имеет значения, потому что вы действительно хотите использовать i
from ;let я = index
в вашем цикле.
Ответ 4
Я не мог нести идею выделения массива для простого повторения компонентов, поэтому я написал структурную директиву. В простейшей форме это не делает индекс доступным для шаблона, он выглядит так:
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
Ответ 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);
}
Проверка на ошибки и утверждения специально для краткости опущены (например, что происходит, если шаг отрицательный).
Ответ 6
Вы можете использовать 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);
}
Я не тестировал код, но он должен работать.
Ответ 7
Вы также можете использовать это
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>
Ответ 8
Поскольку метод 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);
Ответ 9
Если вы хотите увеличить размер массива динамически после нажатия на кнопку, найдите прилагаемое мое динамическое решение (вот как я дошел до этого вопроса).
Выделение необходимых переменных:
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>
Ответ 10
Самый простой способ, который я пробовал
Вы также можете создать массив в вашем компонентном файле и вызывать его с помощью директивы * 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>
Ответ 11
Мое решение:
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>
Ответ 12
Это также может быть достигнуто следующим образом:
HTML:
<div *ngFor="let item of fakeArray(10)">
...
</div>
Машинопись:
fakeArray(length: number): Array<any> {
if (length >= 0) {
return new Array(length);
}
}
Рабочая демонстрация
Ответ 13
<div *ngFor="let number of [].constructor(myCollection)">
<div>
Hello World
</div>
</div>
Это хороший и быстрый способ повторять количество раз в myCollection.