【问题标题】:Angular Material Table Dynamic Columns without model无模型的角材料表动态列
【发布时间】:2018-09-26 19:48:25
【问题描述】:

我需要使用没有模型的角材料表,因为我不知道服务会带来什么。

所以我在这样的组件中动态初始化我的MatTableDataSourcedisplayedColumns

表格组件:

ngOnInit() {

this.vzfPuanTablo = [] //TABLE DATASOURCE

//GET SOMETHING FROM SERVICE 
this.listecidenKisi = this.listeciServis.listecidenKisi;
this.listecidenVazife = this.listeciServis.listecidenVazife;

//FILL TABLE DATASOURCE 
var obj = {};
for (let i in this.listecidenKisi ){
    for( let v of this.listecidenVazife[i].vazifeSonuclar){
        obj[v.name] = v.value;
    }
    this.vzfPuanTablo.push(obj);
    obj={};
}

//CREATE DISPLAYED COLUMNS DYNAMICALLY
this.displayedColumns = [];
for( let v in this.vzfPuanTablo[0]){
    this.displayedColumns.push(v);
}

//INITIALIZE MatTableDataSource
this.dataSource = new MatTableDataSource(this.vzfPuanTablo);
}

代码最重要的部分在这里:

for( let v in this.vzfPuanTablo[0]) {
   this.displayedColumns.push(v);
}

我在这里动态创建displayedColumns,意思是;即使我不知道服务会带来什么,我也可以在表格中展示出来。

例如displayedColumns可以是这样的:

  • [“一”、“二”、“三”、“四”、“五”]

  • ["stack","overflow","help","me]

但这不是问题,因为我可以处理它。


但是当我想在 HTML 中显示它时,我无法正确显示,因为 matCellDef东西:

表格HTML:

    <mat-table #table [dataSource]="dataSource" class="mat-elevation-z8">

        <ng-container *ngFor="let disCol of displayedColumns; let colIndex = index" matColumnDef="{{disCol}}">
            <mat-header-cell *matHeaderCellDef>{{disCol}}</mat-header-cell>
            <mat-cell *matCellDef="let element "> {{element.disCol}}
            </mat-cell>
        </ng-container>

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

我的问题在这里:

<mat-cell *matCellDef="let element "> {{element.disCol}} < / mat-cell>

其实我想在单元格中显示element."disCol's value",但是我不知道该怎么做。

否则,除了 element."disCol's value" 这个东西之外,一切都很好。


当我使用 {{element.disCol}} 显示 value of element that has disCols's value 时,所有单元格都是空的:

仅使用{{element}} 的其他示例:


如您所见:

  1. 表数据源是动态变化的。这意味着我不能轻易使用{{element.ColumnName}},因为我什至不知道它是什么。

    • 第一个示例的显示列 = ['Vazife', 'AdSoyad', 'Kirmizi', 'Mavi', 'Yesil', 'Sari'];
    • 第二个示例的显示列 = ['Muhasebe', 'Ders', 'Egitim', 'Harici'];
  2. matHeaderCellDef 是正确的,因为它直接使用 {{disCol}}。

但我需要读取 disCol 的值,并在单元格中显示 element.(disCol's value)

我该怎么做?

【问题讨论】:

    标签: dynamic interface angular-material datasource


    【解决方案1】:

    我找到了解决方案 :) 这很容易,但一开始我看不到 :) 只有这样:

            <mat-cell *matCellDef="let element "> {{element[disCol]}}
            </mat-cell>
    

    我必须只在 HTML 中使用{{element[disCol]}}

    现在,一切正常:)

    【讨论】:

    • 能否请您发给我完整的示例代码,以从 API 创建动态列并填充网格
    • @Uttam 我在下面添加了一个完整的例子
    • 感谢您指出干净、简单的答案。我正准备让自己再次深入“棱角分明”。 :--)
    • @mevaka,您能否提供创建动态列的完整代码。我在添加列时遇到了这个问题。我正在添加基于按钮单击的列。我的意思是如果有 5 个按钮是 dere 。通过单击每个按钮,列将增加,行也在增加。如果我添加 5 列,将会有 5 行,但我只需要一行。
    • @srikanth 添加到您想要的列中 displayedColumns.push("newCol")
    【解决方案2】:

    关于基于@mevaka's 的完整工作示例

    其中jobDetails$ 是项目数组。

    columns$ 等同于Object.keys(jobDetails$[0]) 所以只是string[]

      <table mat-table [dataSource]="jobDetails$ | async">
    
        <ng-container *ngFor="let disCol of (columns$ | async); let colIndex = index" matColumnDef="{{disCol}}">
          <th mat-header-cell *matHeaderCellDef>{{disCol}}</th>
          <td mat-cell *matCellDef="let element">{{element[disCol]}}</td>
        </ng-container>
    
    
        <tr mat-header-row *matHeaderRowDef="(columns$ | async)"></tr>
        <tr mat-row *matRowDef="let row; columns: (columns$ | async)"></tr>
      </table>
    

    【讨论】:

    • 如果我们有一个动态表,我们可以使用 css 应用不同的列大小吗?我想将我的静态表转换为动态表以支持 2 个不同的视图。
    • @ChandreshMishra 我不明白为什么不,先给它!
    • 但是 ngFor 会在哪里以及如何应用 tr 和 td 的 css 类?
    • 为您的抽象行模型添加一个“数据类型”属性,该属性可用于为每个数据和标题单元格生成一个 CSS 类。例如。数字类型应该右对齐。
    【解决方案3】:

    我已尽力将动态表精简到最低限度。此示例将显示给定具有任何键的平面对象数组的任何列。请注意第一个对象如何具有一个额外的“foo”属性,该属性会导致创建整个列。 DATA const 可能是您从服务中获得的一些数据。此外,如果您知道一些常见的属性名称,您可以在其中添加“列 ID -> 标签”映射,您将获得 JSON。请参阅 stachblitz here

    import {Component, ViewChild, OnInit} from '@angular/core';
    
    const DATA: any[] = [
      {position: 1, name: 'sdd', weight: 1.0079, symbol: 'H', foo: 'bar'},
      {position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
      {position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'},
      {position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be'},
      {position: 5, name: 'Boron', weight: 10.811, symbol: 'B'},
      {position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C'}
    ];
    
    @Component({
      selector: 'dynamic-table-example',
      styleUrls: ['dynamic-table-example.css'],
      templateUrl: 'dynamic-table-example.html',
    })
    export class DynamicTableExample implements OnInit {
    
      columns:Array<any>
      displayedColumns:Array<any>
      dataSource:any
      
      ngOnInit() {
        // Get list of columns by gathering unique keys of objects found in DATA.
        const columns = DATA
          .reduce((columns, row) => {
            return [...columns, ...Object.keys(row)]
          }, [])
          .reduce((columns, column) => {
            return columns.includes(column)
              ? columns
              : [...columns, column]
          }, [])
        // Describe the columns for <mat-table>.
        this.columns = columns.map(column => {
          return { 
            columnDef: column,
            header: column,
            cell: (element: any) => `${element[column] ? element[column] : ``}`     
          }
        })
        this.displayedColumns = this.columns.map(c => c.columnDef);
        // Set the dataSource for <mat-table>.
        this.dataSource = DATA
      }
     
    }
    <mat-table #table [dataSource]="dataSource">
      <ng-container *ngFor="let column of columns" [cdkColumnDef]="column.columnDef">
        <mat-header-cell *cdkHeaderCellDef>{{ column.header }}</mat-header-cell>
        <mat-cell *cdkCellDef="let row">{{ column.cell(row) }}</mat-cell>
      </ng-container>
      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
    </mat-table>

    【讨论】:

    • 这个例子确实帮助我入门,并且最接近文档。唯一不同的是,现在推荐使用 mat-table "Directive": mat-cell *cdkCellDef="let row">{{ column.cell(row) }}
    猜你喜欢
    • 2021-09-03
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    • 2018-09-21
    • 1970-01-01
    相关资源
    最近更新 更多