javascript - 带有动态标题和单元格的 Angular 7 材料表
问题描述
考虑到我从这样的 API 获得了一组对象(用户有选择框来选择年份、类型和输入值):
[
{
"year": 2019,
"type": "Salaries",
"value": 100
},
{
"year": 2019,
"type": "Projects",
"value": 78
},
{
"year": 2018,
"type": "Projects",
"value": 500
},
{
"year": 2018,
"type": "Others",
"value": 500
},
]
我需要像这样每年显示这些数据:
| Year | Salaries | Pojects | Others |
-------------------------------------
| 2019 | 100 | 78 | |
-------------------------------------
| 2018 | | 500 | 500 |
我无法弄清楚的部分是如何遍历数组以构建数组标题,然后每年将正确的值放在相应的类型上......感谢您的帮助。
解决方案
为了实现您的目标,您需要使用从 API 接收的数据创建一个新数组。为了给出我的解决方案,我假设您从 API 收到如下数据数组。
[{ "year": 2019, "type": "Salaries", "value": 100 },
{ "year": 2019, "type": "Projects", "value": 78 },
{ "year": 2018, "type": "Projects", "value": 500 },
{ "year": 2018, "type": "Others", "value": 500 },
{ "year": 2019, "type": "Others", "value": 230 },
{ "year": 2018, "type": "Salaries", "value": 900 }]
要在您的问题中的表格中显示上述数据,您必须将其转换为有意义的数组,如下所示。
[{ "year": 2019, "salary": 100, "project": 78, "other": 230 },
{ "year": 2018, "salary": 900, "project": 500, "other": 500 }]
我假设某年没有相同类型的重复记录,如下所示。
{ "year": 2019, "type": "Salaries", "value": 100 }
{ "year": 2019, "type": "Salaries", "value": 200 }
如果有像上面最后一个元素的重复值将被视为 value。
您必须实现新函数来创建displayData
数组,如下所示。
打字稿
export class MyComponent {
data = [
{ "year": 2019, "type": "Salaries", "value": 100 },
{ "year": 2019, "type": "Projects", "value": 78 },
{ "year": 2018, "type": "Projects", "value": 500 },
{ "year": 2018, "type": "Others", "value": 500 },
{ "year": 2019, "type": "Others", "value": 230 },
{ "year": 2018, "type": "Salaries", "value": 900 }];
displayData: any = [];
constructor() {
this.createDisplayData()
}
createDisplayData(): void {
for (let i = 0; i < this.data.length; i++) {
let type: string;
if (this.data[i].type === "Salaries")
type = 'salary';
else if (this.data[i].type === "Projects")
type = 'project';
else
type = 'other';
const found = this.displayData.find(v => v.year === this.data[i].year);
if (!found) {
let object = {};
object['year'] = this.data[i].year;
object[type] = this.data[i].value
this.displayData.push(object);
}
else {
found[type] = this.data[i].value;
}
}
}
}
HTML
<table style="width: 100%">
<tr>
<th>Year</th>
<th>Salaries</th>
<th>Pojects</th>
<th>Others</th>
</tr>
<tr *ngFor="let data of displayData">
<td style="text-align: center">{{data.year}}</td>
<td style="text-align: center">{{data.salary}}</td>
<td style="text-align: center">{{data.project}}</td>
<td style="text-align: center">{{data.other}}</td>
</tr>
</table>
在此处查找StackBlitz 演示。
更新评论的建议。
其他可以做到这一点的方法是使用Array.reduce()
函数而不是 for 循环,如下所示。
TS
createDisplayData(): void {
this.displayData = this.data.reduce((accumulator, currentValue) => {
const found = accumulator.find(v => v.year === currentValue.year);
if (!found) {
let object = {};
object['year'] = currentValue.year;
object[currentValue.type] = currentValue.value;
accumulator.push(object);
} else {
found[currentValue.type] = currentValue.value;
}
return accumulator;
}, []);
}
HTML
<table style="width: 100%">
<tr>
<th>Year</th>
<th>Salaries</th>
<th>Pojects</th>
<th>Others</th>
</tr>
<tr *ngFor="let data of displayData">
<td style="text-align: center">{{data.year}}</td>
<td style="text-align: center">{{data.Salaries}}</td>
<td style="text-align: center">{{data.Projects}}</td>
<td style="text-align: center">{{data.Others}}</td>
</tr>
</table>
推荐阅读
- java - 如何在 cxf xml 中启用寻址功能?
- sql-server - 带有 MS-SQL 的 apache-nifi PutSQL 处理器:更新语句挂起
- javascript - Javascript:在对象闭包中使用访问器属性
- javascript - 如何在javascript中返回当前函数的函数构造函数对象属性?
- string - 如何使用 Laravel 从名称中提取首字母
- java - Android:切换按钮以使按钮单击动画?
- sql-server - 发出@@IDENTITY AND IDENT_CURRENT(tableName) SQL SERVER
- c++ - Lambda 函数从更高范围返回左值
- android-studio - 无法为 Android Studio 安装 Intel HAXM [已修复]
- command-line - 没有任何插件的命令行代码来解压缩 .zip 文件