【问题标题】:Is there a way to create an Angular dynamic material table on columns and not on rows, with a more complex object dataSource?有没有办法使用更复杂的对象数据源在列而不是行上创建 Angular 动态材料表?
【发布时间】:2021-05-25 06:50:53
【问题描述】:

我想构建一个表,其中每一列都是来自 API 调用的响应并包含一些元素。我用材料表尝试了不同的方法,但似乎没有任何效果。问题在于我尝试在列而不是行上构建它(每个列上的元素数量不同)

我也尝试过使用一个简单的表格,它可以工作,但视图看起来不像它应该的那样。每列都包含在<ng-container> 中,它应该显示为一个新列,但它将它们显示在同一列上。 我还尝试了一种使用 div 的方法,效果很好,但是当我向下滚动时,我无法使表格的标题变得粘滞和固定。 (另外,在表格中使用 div 也不是一个好主意) 这是我的桌子现在的样子,是迄今为止最好的变体:

 <table class="mat-table">
      <ng-container *ngFor="let elem of selectedCheckValues">
        <th class="mat-header-cell">{{ elem.name }}</th>
        <tr id="{{element}}" *ngFor="let element of elem.items; let idx=index;" (click)="onRowClick(elem, element)">
          <td class="mat-cell">{{element}}</td>
        </tr>
      </ng-container>
    </table>

这就是我的数据的样子:

export interface SelectedCheckValues {
  name: string;
  items: string[];
}

其中 name 应该是表头和列中的元素。

【问题讨论】:

    标签: angular html-table material-table angular-material-table fixed-header-tables


    【解决方案1】:

    如果您想在 mat-table 的列中分配一系列调用,您需要使用这些列“创建”一个 DataSource。

    我做了一个简单的例子。在此我想您使用 forkJoin 获取数据,因此您可以拥有类似

      dataSource:any[] = [];
      data=[0,1,2]
      headers:string[]=[]
      constructor(private dataService:DataService){}
      ngOnInit(){
    
        //we make a "typical" forkJoin where transform the "data" in an
        //array of "Observables" and use forkJoin
        forkJoin(this.data.map(x=>this.dataService.getData(x)))
        .subscribe((res:any[])=>{
           //when we has the response we "formed" the dataSource
           let i=0;
           let goon=true;
           this.headers=res.map(x=>x.name)
           while(goon)
           {
              const items=res.map(x=>x.items[i])
              goon=items.find(x=>x!==null)
              this.dataSource.push(items)
              i++;
           }
        })
      }
    

    还有一个.html

    <table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
    
      <ng-container *ngFor="let header of headers;let i=index" [matColumnDef]="header">
        <th mat-header-cell *matHeaderCellDef>{{header}}</th>
        <td mat-cell *matCellDef="let element"> {{element[i]}} </td>
      </ng-container>
    
    
      <tr mat-header-row *matHeaderRowDef="headers"></tr>
      <tr mat-row *matRowDef="let row; columns: headers;"></tr>
    </table>
    

    stackblitz

    顺便说一句,带有粘性的垫子表只有 .css,因此您可以采取使用普通表格和 .css 粘贴“标题”的方法

    更新:我很难想象你是如何获取数据的,如果你使用三个对 api 的调用来获取数据

    getMFTNO() //return some like [101,102,103]
    getDF_RESULT() //return some like ["DL","FM","FT"]
    getPERSNO() //return some like [0,000000,0000001]
    

    所有的api返回相同数量的元素,想法是使用三个调用的forJoin并映射到一个对象数组

    forkJoin([this.getMFTNO(),this.getDF_RESULT(),this.getPERSNO()])
          .pipe(
            map(([mftno,dfResult,persno]:[any[],any[],any[]])=>{
              return mftno.map((x,index)=>(
              { 
                mftno:x,
                dfResult:dfResult[index],
                persno:persno[index]
              }
            ))
            }))
    

    注意:我更新了 stackblitz 以考虑到这一点

    【讨论】:

    • 感谢您的回答,但它不起作用。首先,如果我使用您的示例,列的大小将与不好的 headers 数组的大小相等(我有不同大小的列)。此外,使用您的方法,数据是在行而不是列上构建的。
    • @Catleen,你是如何获得“数据”的?如果我们有三个电话,我会更新答案(但在这种情况下电话是固定的)。对不起,如果我把你弄糊涂了:(
    【解决方案2】:

    从我的桌子上剪下它的样子。

    而不是

    【讨论】:

      猜你喜欢
      • 2020-07-24
      • 2023-01-12
      • 1970-01-01
      • 1970-01-01
      • 2019-08-31
      • 1970-01-01
      • 2018-09-21
      • 1970-01-01
      • 2018-10-13
      相关资源
      最近更新 更多