In angular mat-table 根据rowIndex和columnIndex插入数据
In angular mat-table insert data based on rowIndex and columnIndex
我正在尝试创建一个 table 响应如下 行数 & 列数.
在这个 table 中,我有一个 objects 数组,带有 行索引号 和 列索引号,我试图将其相应地显示到 Angular Material Table component
{
"Table": [
{
"NumCols": 4,
"NumRows": 10,
"TableData": [
{
"Id": "1",
"ColumnIndex": 1,
"ColumnSpan": 0,
"RowIndex": 2,
"RowSpan": 0,
"Cell": "Data 1"
},
{
"Id": "2",
"ColumnIndex": 2,
"ColumnSpan": 0,
"RowIndex": 1,
"RowSpan": 0,
"Cell": "Data 2"
},
{
"Id": "3",
"ColumnIndex": 3,
"ColumnSpan": 0,
"RowIndex": 5,
"RowSpan": 0,
"Cell": "Data 3"
},
{
"Id": "4",
"ColumnIndex": 4,
"ColumnSpan": 0,
"RowIndex": 3,
"RowSpan": 0,
"Cell": "Data 4"
},
{
"Id": "5",
"ColumnIndex": 1,
"ColumnSpan": 0,
"RowIndex": 4,
"RowSpan": 0,
"Cell": "Data 5"
},
{
"Id": "6",
"ColumnIndex": 2,
"ColumnSpan": 0,
"RowIndex": 6,
"RowSpan": 0,
"Cell": "Data 6"
},
{
"Id": "7",
"ColumnIndex": 3,
"ColumnSpan": 0,
"RowIndex": 7,
"RowSpan": 0,
"Cell": "Data 7"
},
{
"Id": "8",
"ColumnIndex": 2,
"ColumnSpan": 0,
"RowIndex": 8,
"RowSpan": 0,
"Cell": "Data 8"
},
{
"Id": "9",
"ColumnIndex": 3,
"ColumnSpan": 0,
"RowIndex": 9,
"RowSpan": 0,
"Cell": "Data 9"
},
{
"Id": "10",
"ColumnIndex": 4,
"ColumnSpan": 0,
"RowIndex": 10,
"RowSpan": 0,
"Cell": "Data 10"
}
]
}
]
}
与此类似,没有任何 headers(Column1 等...)
我已经发布了 working solution on Github.
的完整源代码
首先,您需要声明一个接口,以便 TypeScript 知道您的 JSON 是什么数据类型。为简单起见,您可以将接口 属性 名称与 JSON 属性 名称匹配。您可以直接在 component.ts
文件或外部 .ts
文件中执行此操作。
// Create an interface for your data, so TypeScript knows what datatype to work with when
// putting your data in the table.
export interface TableDataInterface {
Id: string;
ColumnIndex: number;
ColumnSpan: number;
RowIndex: number;
RowSpan: number;
Cell: string;
}
现在在你的 component.ts
文件中,声明三个数组:一个用于你的输入数据(从 JSON 响应中读取),一个用于 table 数据(什么您将在 HTML 中绑定),还有一个用于 table 列定义(Angular 对此技术要求的内容):
export class YourComponent {
// ...
// Declare a property on your component to hold the data for your table,
// and initialize it to an empty array.
inputData: TableDataInterface[] = []
// Declare a property on your component to hold the data to be displayed.
// This is what you will bind to from the HTML.
tableData: string[][] = [];
// Declare a property to hold the list of columns to display.
tableColumns: string[] = [];
// ...
}
在你的组件 class 内的适当函数内(我刚刚在 ngOnInit()
内写了我的),你现在有 4 个步骤要完成。
首先,从任何来源获取数据。下面的代码使用本地 JSON 文件。我有 。在从 API 连接到实时数据之前,这有利于测试。连接到实时数据源后,您需要用 API 代码替换 getData()
函数的内容。
import Table from './data/test-data.json'; // Added to support reading data from local json file.
import { TableDataInterface } from '../types/table-data.interface'; // import your interace.
// Added to support reading data from local json file.
let table_data = Table.Table;
export class YourComponent {
// ...
// Use the initialization (or whatever other appropriate function) to populate the
// data of your table.
ngOnInit(): void {
// 1. Get the data from whatever source you are getting it from.
this.inputData = this.getData();
// The next three steps go here ...
}
// ...
// Put your code to get the table data in this function. Here a hard-coded value is
// used as an example.
getData(): TableDataInterface[] {
// NOTE: if your interface properties do not match exactly the json, you will
// need to convert between the two here before returning. In this example
// the two match, so the data can be directly returned.
return table_data[0].TableData;
}
// ...
}
其次,根据 JSON 响应中的数据创建要绑定的二维数组:
// 2. Create a 2D array with a value for each cell initialized to empty string.
for (var row: number = 0; row < table_data[0].NumRows; row++) {
// Initialize the row.
this.tableData[row] = [];
for (var col: number = 0; col < table_data[0].NumCols; col++) {
// Initialize the cell in the row.
this.tableData[row][col] = "";
}
}
第三,为 Angular 创建列数组,以便在渲染 table:
时从中绘制
// 3. Create an entry in the table columns array for each column.
for (var col: number = 0; col < table_data[0].NumCols; col++) {
// Angular requires a unique name for each column, so we will just
// use the index of that column for the name.
this.tableColumns[col] = col.toString();
}
第四,使用 JSON 响应中的 ColumnIndex 和 RowIndex,将初始化二维数组的值替换为 JSON 响应中的值。
// 4. Now replace the values in the table data with the ones you want displayed.
for (var inputIndex: number = 0; inputIndex < this.inputData.length; inputIndex++) {
// NOTE: the -1 for the column and row is to account for the fact that the input data
// is one-indexed, while the arrays are zero-indexed.
this.tableData[this.inputData[inputIndex].RowIndex - 1][this.inputData[inputIndex].ColumnIndex - 1] = this.inputData[inputIndex].Cell;
}
最后,component.html
文件中的 HTML 会很短:
<!-- Bind the data source to the 2D data array in your corresponding .ts file. -->
<table mat-table [dataSource]="tableData">
<!-- Define the column templates. Use an ngFor to create a template for
each column in the array of columns. -->
<mat-text-column *ngFor="let data of tableColumns"
[name]="data"></mat-text-column>
<!-- Uncomment the following line if you want column headers. -->
<!--<tr mat-header-row *matHeaderRowDef="tableColumns"></tr>-->
<tr mat-row *matRowDef="let row; columns: tableColumns;"></tr>
</table>
使用问题中给出的 JSON 的结果将如下所示(来自 运行 本地主机 Github 上发布的代码的屏幕截图):
如果看起来不协调,请使用 table 样式。在上面的屏幕截图中,我使用了以下 CSS:
table {
width: 600px;
margin: 20px;
}
重要限制:该解决方案目前假定没有单元格数据跨越多行或多列。添加它会使事情变得更加困难!
我正在尝试创建一个 table 响应如下 行数 & 列数.
在这个 table 中,我有一个 objects 数组,带有 行索引号 和 列索引号,我试图将其相应地显示到 Angular Material Table component
{
"Table": [
{
"NumCols": 4,
"NumRows": 10,
"TableData": [
{
"Id": "1",
"ColumnIndex": 1,
"ColumnSpan": 0,
"RowIndex": 2,
"RowSpan": 0,
"Cell": "Data 1"
},
{
"Id": "2",
"ColumnIndex": 2,
"ColumnSpan": 0,
"RowIndex": 1,
"RowSpan": 0,
"Cell": "Data 2"
},
{
"Id": "3",
"ColumnIndex": 3,
"ColumnSpan": 0,
"RowIndex": 5,
"RowSpan": 0,
"Cell": "Data 3"
},
{
"Id": "4",
"ColumnIndex": 4,
"ColumnSpan": 0,
"RowIndex": 3,
"RowSpan": 0,
"Cell": "Data 4"
},
{
"Id": "5",
"ColumnIndex": 1,
"ColumnSpan": 0,
"RowIndex": 4,
"RowSpan": 0,
"Cell": "Data 5"
},
{
"Id": "6",
"ColumnIndex": 2,
"ColumnSpan": 0,
"RowIndex": 6,
"RowSpan": 0,
"Cell": "Data 6"
},
{
"Id": "7",
"ColumnIndex": 3,
"ColumnSpan": 0,
"RowIndex": 7,
"RowSpan": 0,
"Cell": "Data 7"
},
{
"Id": "8",
"ColumnIndex": 2,
"ColumnSpan": 0,
"RowIndex": 8,
"RowSpan": 0,
"Cell": "Data 8"
},
{
"Id": "9",
"ColumnIndex": 3,
"ColumnSpan": 0,
"RowIndex": 9,
"RowSpan": 0,
"Cell": "Data 9"
},
{
"Id": "10",
"ColumnIndex": 4,
"ColumnSpan": 0,
"RowIndex": 10,
"RowSpan": 0,
"Cell": "Data 10"
}
]
}
]
}
与此类似,没有任何 headers(Column1 等...)
我已经发布了 working solution on Github.
的完整源代码首先,您需要声明一个接口,以便 TypeScript 知道您的 JSON 是什么数据类型。为简单起见,您可以将接口 属性 名称与 JSON 属性 名称匹配。您可以直接在 component.ts
文件或外部 .ts
文件中执行此操作。
// Create an interface for your data, so TypeScript knows what datatype to work with when
// putting your data in the table.
export interface TableDataInterface {
Id: string;
ColumnIndex: number;
ColumnSpan: number;
RowIndex: number;
RowSpan: number;
Cell: string;
}
现在在你的 component.ts
文件中,声明三个数组:一个用于你的输入数据(从 JSON 响应中读取),一个用于 table 数据(什么您将在 HTML 中绑定),还有一个用于 table 列定义(Angular 对此技术要求的内容):
export class YourComponent {
// ...
// Declare a property on your component to hold the data for your table,
// and initialize it to an empty array.
inputData: TableDataInterface[] = []
// Declare a property on your component to hold the data to be displayed.
// This is what you will bind to from the HTML.
tableData: string[][] = [];
// Declare a property to hold the list of columns to display.
tableColumns: string[] = [];
// ...
}
在你的组件 class 内的适当函数内(我刚刚在 ngOnInit()
内写了我的),你现在有 4 个步骤要完成。
首先,从任何来源获取数据。下面的代码使用本地 JSON 文件。我有 getData()
函数的内容。
import Table from './data/test-data.json'; // Added to support reading data from local json file.
import { TableDataInterface } from '../types/table-data.interface'; // import your interace.
// Added to support reading data from local json file.
let table_data = Table.Table;
export class YourComponent {
// ...
// Use the initialization (or whatever other appropriate function) to populate the
// data of your table.
ngOnInit(): void {
// 1. Get the data from whatever source you are getting it from.
this.inputData = this.getData();
// The next three steps go here ...
}
// ...
// Put your code to get the table data in this function. Here a hard-coded value is
// used as an example.
getData(): TableDataInterface[] {
// NOTE: if your interface properties do not match exactly the json, you will
// need to convert between the two here before returning. In this example
// the two match, so the data can be directly returned.
return table_data[0].TableData;
}
// ...
}
其次,根据 JSON 响应中的数据创建要绑定的二维数组:
// 2. Create a 2D array with a value for each cell initialized to empty string.
for (var row: number = 0; row < table_data[0].NumRows; row++) {
// Initialize the row.
this.tableData[row] = [];
for (var col: number = 0; col < table_data[0].NumCols; col++) {
// Initialize the cell in the row.
this.tableData[row][col] = "";
}
}
第三,为 Angular 创建列数组,以便在渲染 table:
时从中绘制// 3. Create an entry in the table columns array for each column.
for (var col: number = 0; col < table_data[0].NumCols; col++) {
// Angular requires a unique name for each column, so we will just
// use the index of that column for the name.
this.tableColumns[col] = col.toString();
}
第四,使用 JSON 响应中的 ColumnIndex 和 RowIndex,将初始化二维数组的值替换为 JSON 响应中的值。
// 4. Now replace the values in the table data with the ones you want displayed.
for (var inputIndex: number = 0; inputIndex < this.inputData.length; inputIndex++) {
// NOTE: the -1 for the column and row is to account for the fact that the input data
// is one-indexed, while the arrays are zero-indexed.
this.tableData[this.inputData[inputIndex].RowIndex - 1][this.inputData[inputIndex].ColumnIndex - 1] = this.inputData[inputIndex].Cell;
}
最后,component.html
文件中的 HTML 会很短:
<!-- Bind the data source to the 2D data array in your corresponding .ts file. -->
<table mat-table [dataSource]="tableData">
<!-- Define the column templates. Use an ngFor to create a template for
each column in the array of columns. -->
<mat-text-column *ngFor="let data of tableColumns"
[name]="data"></mat-text-column>
<!-- Uncomment the following line if you want column headers. -->
<!--<tr mat-header-row *matHeaderRowDef="tableColumns"></tr>-->
<tr mat-row *matRowDef="let row; columns: tableColumns;"></tr>
</table>
使用问题中给出的 JSON 的结果将如下所示(来自 运行 本地主机 Github 上发布的代码的屏幕截图):
如果看起来不协调,请使用 table 样式。在上面的屏幕截图中,我使用了以下 CSS:
table {
width: 600px;
margin: 20px;
}
重要限制:该解决方案目前假定没有单元格数据跨越多行或多列。添加它会使事情变得更加困难!