Отображение объекта JSON в разных столбцах в 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);
    });

  }

Теперь моя таблица выглядит так:

Моя_Таблица

Но я хочу, чтобы таблица выглядела так:

Desired_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
    }
]

person Virat    schedule 07.01.2020    source источник
comment
привет @Virat, если я сравню ваши данные и изображения (таблица), которые, по вашему мнению, не совпадают, вы можете проверить изображение в соответствии с данными?   -  person kushal shah    schedule 07.01.2020
comment
Изображение только для справки!   -  person Virat    schedule 07.01.2020


Ответы (2)


Попробуйте под кодом

В файле 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 (01.09.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, я пробовал использовать несколько данных и внес изменения в соответствии с данными, сделав его более читаемым и универсальным.

Сообщите мне, если это не сработает.

Спасибо

person kushal shah    schedule 07.01.2020
comment
конечно, @Virat за ваш первый комментарий, я обновил ответ, пожалуйста, посмотрите - person kushal shah; 08.01.2020
comment
Пользовательский интерфейс все еще кажется ломким, хотя он работает на stackblitz !! - person Virat; 08.01.2020
comment
Я понял, мне нужно отладить код и попытаться исправить. дай мне немного времени - person kushal shah; 08.01.2020
comment
@Virat Я обновил ответ, пожалуйста, изучите, внесите необходимые изменения или замените им свой ts-файл - person kushal shah; 08.01.2020
comment
Большое спасибо за ваши усилия. Действительно ценю это! Работает отлично! И последнее: я хочу показать 0 там, где нет tags в столбцах tags и tags_occurence. Подскажите, как мне это сделать? Этого не происходит с * ngIf, тернарный оператор все портит !! - person Virat; 09.01.2020
comment
да, замените k.push(""); val.push(""); на `k.push (0); val.push (0);` или k.push("0");val.push("0"); - person kushal shah; 09.01.2020
comment
@Virat, дайте мне знать, можно ли получить правильный результат с указанным выше изменением или нет? - person kushal shah; 09.01.2020
comment
Ага!! Понятно! Теперь это прекрасно! Большое спасибо за ваши усилия !! - person Virat; 09.01.2020

person    schedule
comment
Эй, это интересное решение! Но это не совсем решает мою проблему. Все данные отображаются в столбце Tag !! - person Virat; 07.01.2020