Angular mat-table 在每一行中显示键值 json 的动态数据

Angular mat-table display dynamic data from key value json in each row

我有以下 json 并想在 material table 中渲染 angular

var res = '[
  {
    "DynamicName": "xyz",
    "DynamicLevel": "xyz",
    "DynamicLevel": "xyz",
    "DynamicLevel": "xyz",
    "dynamic": "xyz"
  },
  {
    "DynamicName": "xyz",
    "DynamicLevel": "xyz",
    "DynamicLevel": "xyz",
    "DynamicLevel": "xyz",
    "dynamic": "xyz"
  },
  {
    "DynamicName": "xyz",
    "DynamicLevel": "xyz",
    "DynamicLevel": "xyz",
    "DynamicLevel": "xyz",
    "dynamic": "xyz"
  }]';

在第二个响应中,这个 json 将如下所示

var res = '[
      {
        "DynamicCity": "xyz",
        "DynamicCountry": "xyz",
        "DynamicState": "xyz",
        "DynamicRegion": "xyz",
        "dynamic": "xyz"
      },
      {
        "DynamicCity": "xyz",
        "DynamicCountry": "xyz",
        "DynamicState": "xyz",
        "DynamicRegion": "xyz",
        "dynamic": "xyz"
      },
      {
        "DynamicCity": "xyz",
        "DynamicCountry": "xyz",
        "DynamicState": "xyz",
        "DynamicRegion": "xyz",
        "dynamic": "xyz"
      }]';

此数据需要在 material 中呈现 table 我试过这样

// properties of the class
displayedColumns: string[];//columns should be create dynamically
dataSource = res;

    <table mat-table [dataSource]="dataSource | keyvalue" class="mat-elevation-z8">
      <ng-container matColumnDef="key">
        <th mat-header-cell *matHeaderCellDef> {{element.key}}</th>
        <td mat-cell *matCellDef="let element"> {{element.value}} </td>
      </ng-container>  
    
      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    </table>

I need output like below

在这里,动态列意味着在每个 api 调用中我们为该列名称获取不同的数据,因此它会在每次 api 调用时更改,所以我无法将它绑定到 material table。 请帮助我解决将 json 数据绑定到 material table 的问题。 参考网址:-

  1. https://www.interfacecreator.com/2018/10/angular-material-table-dynamic.html

Html

<div class="demo-button-container">
  <button mat-raised-button (click)="addData()" class="demo-button">
    Add data
  </button>
  <button
      mat-raised-button
      [disabled]="!dataSource.length"
      (click)="removeData()"
      class="demo-button">
    Remove data
  </button>
</div>

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8 demo-table">
  <!-- Position Column -->
 <ng-container [matColumnDef]="col" *ngFor="let col of displayedColumns">
      <th mat-header-cell *matHeaderCellDef>
        {{col}}
      </th>
      <td mat-cell *matCellDef="let element">
        {{element[col]}}
      </td>
    </ng-container>

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

ts

import {Component, ViewChild} from '@angular/core';
import {MatTable} from '@angular/material/table';

export interface dynElement {
  DynamicName: string,
  DynamicLevel_1: string,
  DynamicLevel_2:string,
  DynamicLevel_3:string,
  dynamic:string
}

const ELEMENT_DATA: any [] = [
  {
    DynamicName: "xyz",
    DynamicLevel_1: "xyz",
    DynamicLevel_2: "xyz",
    DynamicLevel_3: "xyz",
    dynamic: "xyz"
  },
  {
    DynamicName: "xyz",
    DynamicLevel_1: "xyz",
    DynamicLevel_2: "xyz",
    DynamicLevel_3: "xyz",
    dynamic: "xyz"
  },
  {
    DynamicName: "xyz",
    DynamicLevel_1: "xyz",
    DynamicLevel_2: "xyz",
    DynamicLevel_3: "xyz",
    dynamic: "xyz"
  },
  {
    DynamicName: "xyz",
    DynamicLevel_1: "xyz",
    DynamicLevel_2: "xyz",
    DynamicLevel_3: "xyz",
    dynamic: "xyz"
  },
]
@Component({
  selector: 'table-dynamic-array-data-example',
  styleUrls: ['table-dynamic-array-data-example.css'],
  templateUrl: 'table-dynamic-array-data-example.html',
})
export class TableDynamicArrayDataExample {
  
  // your Object Key Object.keys(obj)

  displayedColumns: string[] = [...Object.keys(ELEMENT_DATA[0])];
  dataSource = [...ELEMENT_DATA]; // you can pass your data from backend here

  @ViewChild(MatTable) table: MatTable<any>;

  addData() {
    const randomElementIndex = Math.floor(Math.random() * ELEMENT_DATA.length);
    this.dataSource.push(ELEMENT_DATA[randomElementIndex]);
    this.table.renderRows();
  }

  removeData() {
    this.dataSource.pop();
    this.table.renderRows();
  }
}

演示在 stackblitz

我为你创建了一个 Stackblitz。这应该适用于任何包含具有简单值的对象的列表(将从第一个对象获取键,因此当前列表的所有对象都必须相同(如果不创建单独的表就无法解决这个问题)): https://stackblitz.com/edit/angular-pqgny8?file=src/app/table-basic-example.html

HTML:

<table *ngIf="dataSource && displayedColumns" mat-table [dataSource]="dataSource" class="mat-elevation-z8">

  <ng-container *ngFor="let k of displayedColumns">
    <ng-container [matColumnDef]="k">
      <th mat-header-cell *matHeaderCellDef> {{k}}</th>
      <td mat-cell *matCellDef="let element"> {{element[k]}} </td>
    </ng-container>
  </ng-container>

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

TS:

getData() {
this.dataSource = ELEMENT_DATA; // ELEMENT_DATA is the data from your backend
this.displayedColumns = Object.keys(this.dataSource[0]).map(k => k)

}

 import { Component,OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass']
})
export class AppComponent implements OnInit {
  title = 'jsonDemo';

  ELEMENT_DATA1 = [
    { 'DynamiCCity': 'Hydrogen' , 'DynamicCountry' : 'Country', 'DynamicState' : 'State' , 'DynamicRegion' :'DynamicRegion' , 'dynamic' :'dynamic' },
    { 'DynamiCCity': 'Hydrogen 1' , 'DynamicCountry' : 'Country 1', 'DynamicState' : 'State 1' , 'DynamicRegion' :'DynamicRegion 1' , 'dynamic':'dynamic 1' },
  ];

  displayedColumns: string[] = [];
  dataSource1 = this.ELEMENT_DATA1;
 
  ngOnInit(): void
  {
    this.displayedColumns = Object.getOwnPropertyNames(this.ELEMENT_DATA1[0]);
  }
}


<h2>Demo</h2>

<style>
  table {
  width: 100%;
}
</style>


<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
  <ng-container *ngFor="let item of displayedColumns" matColumnDef="{{item}}">
    <th mat-header-cell *matHeaderCellDef> {{item}} </th>
    <td mat-cell *matCellDef="let element"> {{ element[item] }}</td>
  </ng-container>

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


<router-outlet></router-outlet>

我希望以上代码是您问题的工作演示。它将按预期工作。