Angular 2 - NgFor使用数字代替集合

...例如……

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

?

386444 次浏览

在你的组件中,你可以定义一个number (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]
}
}

查看数组创建的链接:最简洁的方法创建一个整数数组从1..JavaScript 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 {
(...)
}
NgFor还没有使用数字代替集合的方法, 目前,*ngFor只接受一个集合作为参数,但你可以通过以下方法做到这一点

使用管

demo-number.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;
}
}

对于新版本,你必须改变你的导入并删除args[]参数:

import { Pipe, PipeTransform } from '@angular/core';


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

html:

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

# 演示工作

我无法忍受为组件的简单重复分配数组的想法,所以我写了一个结构指令。在最简单的形式中,这并没有使索引对模板可用,它看起来像这样:

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

< a href = " http://plnkr.co/edit/bzoNuL7w5Ub0H5MdYyFR?p =预览noreferrer“rel = > http://plnkr.co/edit/bzoNuL7w5Ub0H5MdYyFR?p =预览< / >

你可以使用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);
}

我没有测试代码,但它应该工作。

请找到附件我的动态解决方案,如果你想在点击按钮后动态增加数组的大小(这就是我如何得到这个问题)。

必要变量的分配:

  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>

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

为了简洁,故意省略错误检查和断言(例如,如果step为负会发生什么)。

这是我试过的最简单的方法

你也可以在你的组件文件中创建一个数组,你可以用*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>

@OP,你太接近你的“不优雅”了。解决方案。

如何:

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

在这里,我从一个空数组Array中获取构造函数:[].constructor,因为Array在模板语法中不是一个可识别的符号,而且我懒得像@pardeep-jain在他的第4个例子中那样在组件typescript中执行Array=Arraycounter = Array。而且我没有调用new,因为从Array构造函数中获取数组并不需要new

Array(30)new Array(30)是等价的。

数组将为空,但这无关紧要,因为你实际上只是想在循环中使用;let i = index中的i

编辑以回复评论:

问:如何使用变量来设置NgFor循环的长度?

下面是一个关于如何呈现具有可变列/行的表的示例

<table class="symbolTable">
<tr *ngFor="let f of [].constructor(numRows); let r = index">
<td class="gridCell" *ngFor="let col of [].constructor(numCols); let c = index">
\{\{gridCards[r][c].name}}
</td>
</tr>
</table>
export class AppComponent implements OnInit {
title = 'simbologia';
numSymbols = 4;
numCols = 5;
numRows = 5;
guessCards: SymbolCard[] = [];
gridCards: SymbolCard[][] = [];


ngOnInit(): void {
for (let c = 0; c < this.numCols; c++) {
this.guessCards.push(new SymbolCard());
}


for (let r = 0; r < this.numRows; r++) {
let row: SymbolCard[] = [];


for (let c = 0; c < this.numCols; c++) {
row.push(
new SymbolCard({
name: '' + r + '_' + c
}))
}
this.gridCards.push(row);
}
}
}

我的解决方案:

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>

你也可以用like that

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

超文本标记语言

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

由于不带参数的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);

这也可以像这样实现:

HTML:

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

打字稿:

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

Working Demo

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

这是一个在myCollection中重复相同次数的好方法。

如果myCollection是5,Hello World会重复5次。

使用自定义结构指令索引:

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

使用管道将数字转换为数组。

@Pipe({
name: 'enumerate',
})
export class EnumeratePipe implements PipeTransform {
transform(n: number): number[] {
return [...Array(n)].map((_,i) => i);
}
}

然后在模板中使用管道。

<p *ngFor="let i of 5 | enumerate">
Index: \{\{ i }}
</p>

https://stackblitz.com/edit/angular-ivy-pkwvyw?file=src/app/app.component.html

My-component.ts

numbers: number[] = [];


constructor() {
this.numbers = new Array<number>(10)
}

My-component.html

<div *ngFor="let num of numbers; let i = index">\{\{ i }}</div>

下面是Angular的一些非常干净和简单的东西:

在.ts:

max = 10;

. html:

<div *ngFor="let dummy of ','.repeat(max).split(','); index as ix">
- \{\{ix + 1}}:
</div>

我认为简单而简短的解决办法就在这里。

你的my.component.ts文件

setArrayFromNumber(i: number) {
return new Array(i);
}

你的my.component.html文件

<li *ngFor='let in of setArrayFromNumber(5); let i = index'>\{\{ i }}</li>

就是这样! !