根据数字使用ngFor重复HTML元素多次


Answers:


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

1
你是对的!更好;-)感谢您指出这一点。我据此更新了答案...
Thierry Templier

6
在第一种方法中,我认为您要说的是arr=Array;
Abdulrahman Alsoghayer '16

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

错误RangeError:无效的数组长度。当要绘制的猫数为零时,这将崩溃。
汤姆·贝弗兰德

真的很喜欢这种简单的方法!
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]"

并使用变量“数字”进行索引。


1
OP说他分配20给一个成员变量..所以这并没有太大帮助
phil294

如果我要迭代200次怎么办?
Chax

1
@Chax你不能。:(
Muhammad bin Yusrat

2
@Chax 200怎么了?*ngFor="let number of [0,1,2,3,4,5...,199,200]":-D
堆栈下溢

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>


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 = _;

然后,您可以使用range函数。可以用组件中的任何变量替换20。

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

必须说,绑定到视图中的函数可能会很昂贵,这取决于您要调用的函数的复杂性,因为变更检测将反复调用该函数。


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 {}
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.