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

Mar*_* Jr 166 angular

...例如...

<div class="month" *ngFor="#item of myCollection; #i = index">
...
</div>
Run Code Online (Sandbox Code Playgroud)

有可能做......

<div class="month" *ngFor="#item of 10; #i = index">
...
</div>
Run Code Online (Sandbox Code Playgroud)

...没有诉诸非优雅的解决方案,如:

<div class="month" *ngFor="#item of ['dummy','dummy','dummy','dummy','dummy',
'dummy','dummy','dummy']; #i = index">
...
</div>
Run Code Online (Sandbox Code Playgroud)

Thi*_*ier 170

在组件中,您可以定义一个数字数组(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]
  }
}
Run Code Online (Sandbox Code Playgroud)

请参阅此链接以了解数组创建:在JavaScript中从1..20创建整数数组的最常用方法.

然后,您可以使用以下代码迭代此数组ngFor:

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

或者很快:

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

  • 在Angular 2 Typescript中使用`Array.fill()`会产生以下错误:提供的参数与调用t arget的任何签名都不匹配. - 检查Array.prototype.fill文档,它说它需要1个参数... https ://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/fill (21认同)
  • `Array(5).fill(1).map((x, i) =&gt; i + 1); /*[1,2,3,4,5]*/` 这解决了 TS 中的错误 (16认同)
  • 是的,蒂埃里!事实上,这不是你的错,但仍然在同一背景下:(它根本不优雅.但由于你是一个非常熟练的A2开发人员,我可以假设没有更好的解决方案.这很难过! (5认同)
  • PS:@View注释已在angular2 beta 10及更高版本中删除. (3认同)

Par*_*ain 75

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>
Run Code Online (Sandbox Code Playgroud)

直接在HTML中使用数字数组(查看)

<ul>
  <li>Method Second</li>
  <li *ngFor='let key of  [1,2]'>
    {{key}}
  </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

使用Split方法

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

使用在组件中创建新数组

<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);
  }
}
Run Code Online (Sandbox Code Playgroud)

工作演示

  • 您还可以使用`Array.fill()`方法生成数组而不是`res.push()`,如Thierrys答案中所示. (4认同)
  • 不,还是一个很好的解决方案+1.我发现`Array.fill()`比使用push的循环更优雅,它也可能更高效. (3认同)
  • 我喜欢这个带有`counter = Array`的解决方案,非常聪明;) (2认同)

jca*_*ney 54

@OP,你非常接近你的"非优雅"解决方案.

怎么样:

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

在这里,我Array从一个空数组中得到构造函数:[].constructor因为Array在模板语法中不是一个可识别的符号,而且我太懒了,Array=Array或者counter = Array像@ pardeep-jain这样的组件打字稿在他的第四个例子中做了.我正在调用它,new因为new没有必要从Array构造函数中获取数组.

Array(30)并且new Array(30)是等价的.

数组将是空的,但是这并不重要,因为你真的只是想用i来自;let i = index于你的循环.

  • 这是最好的答案。 (9认同)
  • @Tobias81,我已经检查过,通过将 print 语句放在我作为示例 ngFor 指令的子级创建的组件的构造函数中,以确保更改检测不会重复重新创建 ngFor 的内容。我没有看到在每次变更检测迭代中重新创建组件,所以我认为实际上不存在问题(至少在 Angular 8 中)。 (2认同)

pdu*_*its 10

我无法承受为明确重复组件分配数组的想法,所以我编写了一个结构指令.在最简单的形式中,这不会使索引可用于模板,它看起来像这样:

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);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 当然,也是一个写指令的练习.另一方面,它不长于管道,这将是第二个理智的方法. (3认同)

yoo*_*ooy 10

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

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

然后在模板中使用管道。

<p *ngFor="let i of 5 | enumerate">
   Index: {{ i }}
</p>
Run Code Online (Sandbox Code Playgroud)

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


小智 6

你也可以这样使用

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

HTML

<p *ngFor="let i of numbers">
   {{i}}
</p>
Run Code Online (Sandbox Code Playgroud)


小智 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);
}
Run Code Online (Sandbox Code Playgroud)

可以在这样的组件中使用它:

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

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

  • html 中的`&lt;div *ngfor="let i of 4, i++"&gt;&lt;/div&gt;` 中是否有任何方法可能是 (2认同)

Adr*_*rma 5

这也可以这样实现:

HTML:

<div *ngFor="let item of fakeArray(10)">
     ...
</div>
Run Code Online (Sandbox Code Playgroud)

打字稿:

fakeArray(length: number): Array<any> {
  if (length >= 0) {
    return new Array(length);
  }
}
Run Code Online (Sandbox Code Playgroud)

工作演示