在 Angular 的不同列中呈现 JSON 对象?

Rendering JSON object in different columns in Angular?

我的 mat-table 脚本:

<table mat-table....>

  ......

  <ng-container matColumnDef="tag">
    <th mat-header-cell *matHeaderCellDef>Tag</th>
    <td mat-cell *matCellDef="let element">{{element.tags}}</td>
  </ng-container>

  <ng-container matColumnDef="tag_occurence">
    <th mat-header-cell *matHeaderCellDef>Tag Occurence</th>
    <td mat-cell *matCellDef="let element"></td>
  </ng-container>

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

</table>

我的服务有以下脚本:

getSolutionInfo(){
    let url = this.baseurl + .... + "/solutionInfo";

    return this.http.get<any>(url).subscribe(res => {
      res.forEach(_entry => {
        _entry.tags = JSON.stringify(_entry.tags);
      });
      this.datasetSubject.next(res);
    });

  }

现在,我的 table 看起来像这样:

但我希望 table 看起来像这样:

我已参考 ,但无法提出解决方案。有人可以帮我解决这个问题吗?

需要渲染的数据:

[
    {
        "solution_name": "TW",
        "total_images": 360,
        "tags": {
            "TR": 1399,
            "NOTCH": 355,
            "DR": 348,
            "DC": 349,
            "DL": 349,
            "TW": 1396,
            "TL": 1399,
            "DT": 348
        },
        "tagged_images": 0
    },
    {
        "solution_name": "TestSolution",
        "total_images": 0,
        "tags": {},
        "tagged_images": 0
    }
]
I think this solution can help you out:

Ts file:

    displayedColumns = ['solution','images', 'tag', 'tag_occurence'];
      dataSource = [
      { 
        solution: 'TW', 
        images:'1500',
        array: [
          { 
            tag: 'TW',
            tag_occurence: 300
          },
          { 
            tag: 'TC',
            tag_occurence: 500
          },
          { 
            tag: 'node',
            tag_occurence: 250
          },
        ] 
      },
      { 
        solution: 'TL', 
        images:'1600',
        array: [
          { 
            tag: 'DC',
            tag_occurence: 300
          },
          { 
            tag: 'DQ',
            tag_occurence: 500
          },
          { 
            tag: 'DL',
            tag_occurence: 250
          },
        ] 
      }
    ];


HTML:



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

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

        <ng-container matColumnDef="solution">
          <mat-header-cell *matHeaderCellDef> Solution </mat-header-cell>
          <mat-cell *matCellDef="let obj"> {{obj.solution}} </mat-cell>
        </ng-container>

        <ng-container matColumnDef="images">
          <mat-header-cell *matHeaderCellDef> Images </mat-header-cell>
          <mat-cell *matCellDef="let obj"> {{obj.images}} </mat-cell>
        </ng-container>

        <ng-container matColumnDef="tag">
          <mat-header-cell *matHeaderCellDef> Tag </mat-header-cell>
          <mat-cell *matCellDef="let obj">
            <mat-cell *ngFor="let book of obj.array">
               {{book.tag}} 
            </mat-cell>
          </mat-cell>
        </ng-container>

        <ng-container matColumnDef="tag_occurence">
          <mat-header-cell *matHeaderCellDef> Tag Occurences </mat-header-cell>
          <mat-cell *matCellDef="let obj">
            <mat-cell *ngFor="let book of obj.array">
               {{book.tag_occurence}} 
            </mat-cell>
          </mat-cell>
        </ng-container>

      </mat-table>
    </div>

CSS:


.mat-table {
 border: 1px solid black;
}
.mat-table .mat-cell {
    display: flex;
    text-align: center;
    flex-direction: column;
    justify-content: center;
}

.mat-table .mat-cell {
  min-height: 60px;
  width: 100%;
  border-bottom: 0.5px solid grey;
}

.mat-table .mat-cell:last-child {
  border-bottom: none;
}

试试下面的代码

在AppComponent.Ts文件中

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  dataSource = [];
  displayedColumns = ['solution_name', 'total_images', 'tagged_images', 'tags','tag_occurence'];
  spans = [];
  tempRowId = null;
  tempRowCount = null;

   orgD = [];

   myData = [
    {
        "solution_name": "TW",
        "total_images": 360,
        "tags": {
            "TR": 1399,
            "NOTCH": 355,
            "DR": 348,
            "DC": 349,
            "DL": 349,
            "TW": 1396,
            "TL": 1399,
            "DT": 348
        },
        "tagged_images": 0
    },
    {
        "solution_name": "TestSolution",
        "total_images": 0,
        "tags": {
          "NOTCH": 355,
            "DR": 348,
        },
        "tagged_images": 1
    }
    ];



 constructor() {
     this.orgD =  this.makeData();
      this.dataSource = this.orgD.reduce((current, next) => {
          for(var d = 0 ; d < next.tags.length ; d++){
              current.push({ solution_name: next.solution_name, total_images: next.total_images, tagged_images: next.tagged_images, tags: next.tags[d],tag_occurence:next.tag_occurence[d] })
          }
  return current;
}, []);
     this.cacheSpan('solution_name', d => d.solution_name);
    this.cacheSpan('total_images', d => d.total_images);
    this.cacheSpan('tagged_images', d => d.tagged_images);
}

makeData = () => {
  let finalData = [];
    this.myData.forEach(d => {
      let a ={};
      a['solution_name'] = d.solution_name; 
      a['total_images'] = d.total_images; 
      a['tagged_images'] = d.tagged_images; 
      if(!!d.tags){
        let k = [];
        let val = [];
          Object.keys(d.tags).forEach(function(key) {
              console.log(key, d.tags[key]);
              k.push(key);
              val.push(d.tags[key]);
          });
          a['tags'] = k;
          a['tag_occurence'] = val;
      }else{
          a['tags'] = [];
          a['tag_occurence'] = [];
      }
   finalData.push(a);
    });
    return finalData;
}

  cacheSpan(key, accessor) {
    for (let i = 0; i < this.dataSource.length;) {
      let currentValue = accessor(this.dataSource[i]);
      let count = 1;
      for (let j = i + 1; j < this.dataSource.length; j++) {
        if (currentValue != accessor(this.dataSource[j])) {
          break;
        }
        count++;
      }
      if (!this.spans[i]) {
        this.spans[i] = {};
      }
      this.spans[i][key] = count;
      i += count;
    }
  }
  getRowSpan(col, index) {    
    return this.spans[index] && this.spans[index][col];
  }
}

在Html文件中

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

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

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

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

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

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

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



</table>

根据您的图片和数据,我理解并已根据它进行了更改。

希望对您有所帮助

如果我做错了什么,请告诉我。

输出图像

根据要求更新功能

makeData = () => {
  let finalData = [];
    this.myData.forEach(d => {
      let a ={};
      a['solution_name'] = d.solution_name; 
      a['total_images'] = d.total_images; 
      a['tagged_images'] = d.tagged_images; 
      if(!!d.tags && Object.keys(d.tags).length >= 1){
        let k = [];
        let val = [];
          Object.keys(d.tags).forEach(function(key) {
              console.log(key, d.tags[key]);
              k.push(key);
              val.push(d.tags[key]);
          });
          a['tags'] = k;
          a['tag_occurence'] = val;
      }else{
        let k = [];
        let val = [];
          k.push("");
          val.push("");
          a['tags'] = k;
          a['tag_occurence'] = val;
      }
   finalData.push(a);
    });
    return finalData;
}

更新 TS 文件 (9-1-2020)

import { Component } from "@angular/core";
@Component({
  selector: "table-basic-example",
  styleUrls: ["table-basic-example.css"],
  templateUrl: "table-basic-example.html"
})
export class TableBasicExample {
  dataSource = [];
  displayedColumns = [
    "solution_name",
    "total_images",
    "tagged_images",
    "tags",
    "tag_occurence"
  ];
  spans = [];
  tempRowId = null;
  tempRowCount = null;
  orgD = [];
  myData = [
    {
      solution_name: "TW",
      total_images: 360,
      tags: {
        TR: 1399,
        NOTCH: 355,
        DR: 348,
        DC: 349,
        DL: 349,
        TW: 1396,
        TL: 1399,
        DT: 348
      },
      tagged_images: 0
    },
    {
      solution_name: "TestSolution3",
      total_images: 0,
      tags: {
        NOTCH: 355,
        DR: 348
      },
      tagged_images: 0
    },
    {
      solution_name: "TestSolution3",
      total_images: 0,
      tags: {
        NOTCH: 355,
        DR: 348
      },
      tagged_images: 0
    },
    {
      solution_name: "TestSolution3",
      total_images: 0,
      tags: {
        NOTCH: 355,
        DR: 348
      },
      tagged_images: 3
    },
    {
      solution_name: "TestSolution3",
      total_images: 4,
      tags: {},
      tagged_images: 0
    }
  ];
  constructor() {
    this.orgD = this.makeData();
    this.dataSource = this.orgD.reduce((current, next) => {
      for (var d = 0; d < next.tags.length; d++) {
        current.push({
          solution_name: next.solution_name,
          total_images: next.total_images,
          tagged_images: next.tagged_images,
          tags: next.tags[d],
          tag_occurence: next.tag_occurence[d]
        });
      }
      return current;
    }, []);
    this.makeSpan();
  }

  makeSpan = () => {
    this.spans = [];
    let index = 0;
    this.myData.forEach(a => {
      let d = {};
      d["solution_name"] =
        Object.keys(a.tags).length >= 1 ? Object.keys(a.tags).length : 1;
      d["total_images"] =
        Object.keys(a.tags).length >= 1 ? Object.keys(a.tags).length : 1;
      d["tagged_images"] =
        Object.keys(a.tags).length >= 1 ? Object.keys(a.tags).length : 1;
      this.spans[index] = d;
      index += d["solution_name"];
    });
  };

  makeData = () => {
    let finalData = [];
    this.myData.forEach(d => {
      let a = {};
      a["solution_name"] = d.solution_name;
      a["total_images"] = d.total_images;
      a["tagged_images"] = d.tagged_images;
      if (!!d.tags && Object.keys(d.tags).length >= 1) {
        let k = [];
        let val = [];
        Object.keys(d.tags).forEach(function(key) {
          k.push(key);
          val.push(d.tags[key]);
        });
        a["tags"] = k;
        a["tag_occurence"] = val;
      } else {
        let k = [];
        let val = [];
        k.push("");
        val.push("");
        a["tags"] = k;
        a["tag_occurence"] = val;
      }
      finalData.push(a);
    });
    return finalData;
  };
  getRowSpan(col, index) {
    return this.spans[index] && this.spans[index][col];
  }
}

将上面的代码替换为ts文件,我已经尝试了多个数据并根据数据进行了更改使其更具可读性和通用性。

如果它不起作用,请告诉我。

谢谢