基于数据源对象数组属性大小的角度材料表行跨列 [英] Angular Material Table rowspan columns based on dataSource object array property size

查看:20
本文介绍了基于数据源对象数组属性大小的角度材料表行跨列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使在 Angular Material 7.2 版本中,我似乎也找不到关于如何在 mat-table 上使用 rowspan 并保持组件功能的示例.

Even now in version 7.2 of Angular Material, I can't seem to find examples on how to use rowspan on mat-table and keep the component functionality.

这是多远(短?)我有:

This is how far (short?) I've got:

https://stackblitz.com/edit/angular-wudscb

上面 Stackblitz 中的示例几乎"是我正在寻找的,但我不知道如何完成它.

The example in the Stackblitz above is "almost" what I am looking for, but I am not being able to see how to finish it.

...
===============================================
||     ||            ||            ||  row1  ||
||  1  ||  Hydrogen  ||   1.0079   ||========||
||     ||            ||            ||  row2  ||
===============================================
||     ||            ||            ||  row1  ||
||     ||            ||            ||========||
||  2  ||   Helium   ||   4.0026   ||  row2  ||
||     ||            ||            ||========||
||     ||            ||            ||  row3  ||
===============================================
||     ||            ||            ||  row1  ||
||  3  ||  Lithium   ||   6.941    ||========||
||     ||            ||            ||  row2  ||
===============================================
...

可以在以下位置找到使用其他元数据格式的示例:

An example using other metadata format can be found in:

https://stackblitz.com/edit/angular-lnahlh

按照我的 Stackblitz(第一个链接),我的问题是:

Following my Stackblitz (the first link), my questions are:

我距离实现这个 rowspan shim/hack 太远了吗?

Am I too far of achieving this rowspan shim/hack?

如何根据行的长度['descriptions'] 大小循环行?

How do I loop the rows based on the lenght of the row['descriptions'] size?

如果我在对象中有另一个数组属性怎么办?我可以迭代并生成具有其大小的列/行/行跨度,使其变得更通用吗?

What If I had another array property inside the object? Could I iterate and generate the columns/rows/rowspan with its size, so it would become more generic?

我正在尝试为社区找到通用的解决方案.

I'm trying to find a generic solution for the community.

推荐答案

好吧,看来材料表没有 api 文档,我也找不到任何技巧来做到这一点,但我们可以将我们的数据 twick to支持这一点,根据你的第二个例子,我们可以将数据重新转换为新的 json,我们可以获得预期的结果.

Well, it seems that material table has no api documentation for it, I could not find any trick to do this too, But we can twick the our data to support this, as per your second example we can reform the data to new json and we can get our expected result.

    const originalData = [
      { id: 1, name: 'Hydrogen', weight: 1.0079, descriptions: ['row1', 'row2'] },
      { id: 2, name: 'Helium', weight: 4.0026, descriptions: ['row1', 'row2', 'row3'] },
      { id: 3, name: 'Lithium', weight: 6.941, descriptions: ['row1', 'row2'] },
      { id: 4, name: 'Beryllium', weight: 9.0122, descriptions: ['row1', 'row2', 'row3'] },
      { id: 5, name: 'Boron', weight: 10.811, descriptions: ['row1'] },
      { id: 6, name: 'Carbon', weight: 12.0107, descriptions: ['row1', 'row2', 'row3'] },
      { id: 7, name: 'Nitrogen', weight: 14.0067, descriptions: ['row1'] },
      { id: 8, name: 'Oxygen', weight: 15.9994, descriptions: ['row1'] },
      { id: 9, name: 'Fluorine', weight: 18.9984, descriptions: ['row1', 'row2', 'row3'] },
      { id: 10, name: 'Neon', weight: 20.1797, descriptions: ['row1', 'row2', 'row3'] },
    ]; //original data

    const DATA = originalData.reduce((current, next) => {
      next.descriptions.forEach(b => {
        current.push({ id: next.id, name: next.name, weight: next.weight, descriptions: b })
      });
      return current;
    }, []);//iterating over each one and adding as the description 
    console.log(DATA)

    const ELEMENT_DATA: PeriodicElement[] = DATA; //adding data to the element data

步骤 2

这将是您的第二个 stackblitz 链接.

Step 2

this will be as it is as your second stackblitz link.

 getRowSpan(col, index) {    
    return this.spans[index] && this.spans[index][col];
  }

步骤 3

正如你的第二个链接

Step 3

as it is as per your second link

  constructor() {
    this.cacheSpan('Priority', d => d.id);
    this.cacheSpan('Name', d => d.name);
    this.cacheSpan('Weight', d => d.weight);
  }

  /**
   * Evaluated and store an evaluation of the rowspan for each row.
   * The key determines the column it affects, and the accessor determines the
   * value that should be checked for spanning.
   */
  cacheSpan(key, accessor) {
    for (let i = 0; i < DATA.length;) {
      let currentValue = accessor(DATA[i]);
      let count = 1;

      // Iterate through the remaining rows to see how many match
      // the current value as retrieved through the accessor.
      for (let j = i + 1; j < DATA.length; j++) {
        if (currentValue != accessor(DATA[j])) {
          break;
        }

        count++;
      }

      if (!this.spans[i]) {
        this.spans[i] = {};
      }

      // Store the number of similar values that were found (the span)
      // and skip i to the next unique row.
      this.spans[i][key] = count;
      i += count;
    }
  }

步骤 4

使用索引向下传递到 rowspan 并隐藏不需要的行

Step 4

Using index to pass down to rowspan and hiding the rows where it doesn't needed

    <ng-container matColumnDef="id">
        <th mat-header-cell *matHeaderCellDef> Priority </th>
        <td mat-cell *matCellDef="let data;let i = dataIndex" [attr.rowspan]="getRowSpan('Priority',i)" [style.display]="getRowSpan('Priority', i) ? '' : 'none'">
         {{ data.id }} </td>
    </ng-container>

    <ng-container matColumnDef="name">
        <th mat-header-cell *matHeaderCellDef> Name </th>
        <td mat-cell *matCellDef="let data;let i = dataIndex" [attr.rowspan]="getRowSpan('Name',i)" [style.display]="getRowSpan('Name', i) ? '' : 'none'">
         {{ data.name }} </td>
    </ng-container>

    <ng-container matColumnDef="weight">
        <th mat-header-cell *matHeaderCellDef> Weight </th>
        <td mat-cell *matCellDef="let data;let i = dataIndex" [attr.rowspan]="getRowSpan('Weight',i)" [style.display]="getRowSpan('Weight', i) ? '' : 'none'">
         {{ data.weight }} </td>
    </ng-container>

    <ng-container matColumnDef="descriptions">
        <th mat-header-cell *matHeaderCellDef> Descriptions </th>
        <td mat-cell *matCellDef="let data"> {{ data.descriptions }} </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> 


</table>

这里是演示

这篇关于基于数据源对象数组属性大小的角度材料表行跨列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆