Forms / Angular 4 - 以动态列数显示组件数组的元素

时间:2017-06-24 17:16:34

标签: arrays forms angular

我的目标是在动态变化的多个列中显示给定数组元素的元素。

示例: 让我们说我们有以下数组:

a b c 
d e f
g h

如果列数为3,则此数组元素的显示为:

a b c d e
f g h

否则,如果列数为5,则显示为:

columnsNumber

实施

我实现了一个在this Plunker中用于我的目的的解决方案(列数存储在变量displayFormat="D"中),但它是纯粹的算法,我想知道是否会有更好的解决方案。

用途:

此解决方案可用于构建动态表单,其中每列包含表单的控件或组件。

1 个答案:

答案 0 :(得分:1)

您在 plunker 中使用的方法的主要问题是每个ChangeDetection都会调用函数“initArrayOfNumbers”。< / p>

要解决您的问题,我建议您使用SlicePipe,如下所示:

<div *ngFor="let i of rows">
  <span *ngFor="let col of columns | slice: (i * columnSize): (i + 1) * columnSize">
    {{ col.name }}
  </span>
</div>

此处定义了rows

this.rows = Array.from({ length: Math.ceil(this.columns.length / this.columnSize) }, (v, k) => k);

<强>解释

这是一个包含生成序列的简单数组,即:如果columnSize为3且您的数组介于(包括)6和9(含)rows之间,则为[0, 1, 2],所以您可以使用它来对SlicePipe进行计算。

您可以查看此简单DEMO以查看其是否有效。

如果您正在寻找更通用的解决方案,可以创建自定义pipe

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

@Pipe({
  name: 'chunk'
})
export class ChunkPipe implements PipeTransform {

  transform(input: any, size: number): any {

    if (!Array.isArray(input) || !size) {
      return [];
    }

    const intSize: number = parseInt(size, 10);
    return Array.from({ length: Math.ceil(input.length / intSize) }, (v, k) => input.slice(k * intSize, k * intSize + intSize));
  }
}

<强>模板

<div *ngFor="let col of columns | chunk: columnSize">
  <span *ngFor="let item of col">
    {{ item.name }}
  </span>
</div>

另外,不要忘记将管道添加到NgModule

中的声明中
@NgModule({
  ...
  declarations: [
    // Other declarations
    ChunkPipe
  ],
  ...
})

DEMO