基于数字使用 ngFor 多次重复 HTML 元素

Posted

技术标签:

【中文标题】基于数字使用 ngFor 多次重复 HTML 元素【英文标题】:Repeat HTML element multiple times using ngFor based on a number 【发布时间】:2016-07-31 20:15:16 【问题描述】:

如何使用*ngFor 多次重复一个 html 元素?

例如: 如果我有一个分配给 20 的成员变量。如何使用 *ngFor 指令使 div 重复 20 次?

【问题讨论】:

另见***.com/questions/47586525/… 四种方法可以达到相同的效果,请在此处阅读。 ***.com/a/36356629/5043867 【参考方案1】:

您可以使用以下内容:

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

【讨论】:

FillPipe 类必须实现 PipeTransform 是的,你是对的!更好;-) 感谢您指出这一点。我相应地更新了我的答案...... 在第一种方法中,我想你的意思是说arr=Array; ? 你能做一个codepen吗?它不起作用:self.parentView.context.arr 不是函数 感谢第一种方法!我没有使用 .fill(1) 并且正在工作 ;)【参考方案2】:

您可以在 HTML 中简单地执行此操作:

*ngFor="let number of [0,1,2,3,4,5...,18,19]"

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

【讨论】:

OP 说他将20 分配给一个成员变量.. 所以这不会有太大帮助 如果我想迭代 200 次怎么办? @Chax 你不能。 :( @Chax 200 有什么问题? *ngFor="let number of [0,1,2,3,4,5...,199,200]" :-D @StackUnderflow 遗憾的是,我没有按角色付费。如果我是,我会宣扬这是实现这一目标的唯一方法:P(真的只是不要;))【参考方案3】:

更简单的方法:

定义一个 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>

【讨论】:

【参考方案4】:

使用Arrays的推荐解决方案有两个问题:

    太浪费了。尤其是对于大量数据。 您必须在某个地方定义它们,这样一个简单而常见的操作会导致很多混乱。

定义一个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>

【讨论】:

所以 有效!感谢 Andreas,您已经设法在 HTML 中模拟了众所周知的 for next 循环:thumbsup【参考方案5】:

一个更简单且可重用的解决方案可能是使用这样的自定义结构指令。

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>

【讨论】:

了解更多信息:netbasal.com/… 这个方案需要在for循环前加上this.viewContainer.clear();【参考方案6】:
<div *ngFor="let dummy of ' '.repeat(20).split(''), let x = index">

用你的变量替换20

【讨论】:

这绝对是一个很好的答案 重复次数应为 19;长度-1。 一个非常不方便的问题的优雅解决方案。但我猜它会对大量元素产生性能影响? 工作正常!谢谢【参考方案7】:

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

【讨论】:

【参考方案8】:

如果您使用Lodash,您可以执行以下操作:

将Lodash 导入到您的组件中。

import * as _ from "lodash";

在组件中声明一个成员变量来引用 Lodash。

lodash = _;

那么在您看来,您可以使用range function。 20 可以替换为组件中的任何变量。

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

必须说,绑定到视图中的函数可能代价高昂,具体取决于您调用的函数的复杂性,因为更改检测会重复调用该函数。

【讨论】:

【参考方案9】:

实现这一点的最有效和最简洁的方法是添加一个迭代器实用程序。不要费心产生价值。不要费心在 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;

【讨论】:

【参考方案10】:
<ng-container *ngFor="let i of [].constructor(20)">?</ng-container>

生成????????????????????

【讨论】:

这应该是正确的答案。。这是迄今为止最简洁的! 错误 RangeError:数组长度无效。当要绘制的猫的数量为零时,这将崩溃。 真的很喜欢这种简单的方法! 实际上最好使用_ 作为变量名,因为iundefined 结尾(因为数组是空的)。如果您确实需要索引,您可以使用*ngFor="let _ of [].constructor(20); let catNumber=index",然后Cat number catNumber + 1 ? 将向您显示猫号。如果你有嵌套循环,你可以为每个循环使用_,它们不会冲突。【参考方案11】:

您不需要像大多数答案中建议的那样填充数组。如果您在 ngFor 循环中使用索引,您只需创建一个具有正确长度的空数组:

const elements = Array(n); // n = 20 in your case

在你看来:

<li *ngFor="let element in elements; let i = index">
  <span> i </span>
</li>

【讨论】:

【参考方案12】:

我知道你特别要求使用 *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>

【讨论】:

这就是我要找的东西! 代码可能会更短...这是我的版本@Input() set smpClone(loops: number) while (--loops &gt; 0) this._viewContainerRef.createEmbeddedView(this._templateRef); 【参考方案13】:

您可以简单地使用它:

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 

【讨论】:

【参考方案14】:

你可以这样做:

Ts:

   CreateTempArray(number)
   var arr=[];
   for(let i=0;i<number;i++)
     arr[i]="";
   
   return arr;
  

HTML:

<div *ngFor="let i of CreateTempArray(20);">
    cycle 20 times
</div>

【讨论】:

【参考方案15】:

进行第 n 次重复的最佳且简单的方法是 [].constructor(nth)

5次循环示例

 <ng-container *ngFor="let _ of [].constructor(5); let i = index">
    <b> i </b>
 </ng-container>

【讨论】:

以上是关于基于数字使用 ngFor 多次重复 HTML 元素的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有 ngFor 和没有另一个 @Component 的情况下多次重复一段 HTML?

直接在 ngFor Angular 中重复两个元素

Angular:如何使用 *ngFor 将指令绑定到元素

<td></td> 元素上的 *ngIf 和 *ngFor [重复]

Angular 5 - 在 *ngFor 内部调用的 Mat-tab 方法被多次执行

Angular,如何使用 *ngFor 或 HTML 表的任何重复设置行 ID