在 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文件,我已经尝试了多个数据并根据数据进行了更改使其更具可读性和通用性。
如果它不起作用,请告诉我。
谢谢
我的 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文件,我已经尝试了多个数据并根据数据进行了更改使其更具可读性和通用性。
如果它不起作用,请告诉我。
谢谢