如何在 Angular 中使用排序处理多个动态创建的表?
How to handle multiple dynamically created tables with soring in Angular?
我有多个动态创建的 Angular table,每个都显示相同的列但具有不同的数据。我需要分别对每个 table 中的列进行排序。我目前有两个 table。当我点击第一个 header 列的箭头时,它排序正确。单击第二个 table 中的同一列没有任何反应。
这里是相关的html:
<div appMaterialElevation *ngFor="let item of tables; let i = index">
<table
mat-table
[dataSource]="item.dataSource"
multiTemplateDataRows
matSort
matSortActive="configName"
matSortDirection="asc"
>
<ng-container matColumnDef="configName">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Table Name</th>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
</div>
这是相关的TS:
import { Component, ViewChild, ViewChildren, QueryList, OnInit, AfterViewInit, OnDestroy } from '@angular/core';
export class Row {
configName: string;
}
export class FormatData {
formatName: string;
dataSource: MatTableDataSource<Row>;
selection: SelectionModel<Row>;
}
export class ConfigureFormatsComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChildren(MatPaginator) paginators = new QueryList<MatPaginator>();
@ViewChildren(MatSort) sorts = new QueryList<MatSort>();
tables: FormatData[];
displayedColumns: string[] = ['configName'];
getconfigformats() {
this.tables = [] as FormatData[];
this.myService.getMyData()
.subscribe((configList: MyConfigs[]) => {
let table = new FormatData();
let configNamesList = [] as Row[];
configList.forEach(config => {
let row = new Row();
row.configName = config.configName;
configNamesList.push(row);
});
table.dataSource = new MatTableDataSource<Row>(configNamesList);
table.selection = new SelectionModel<Row>(true, []);
this.tables.push(table);
this.ngAfterViewInit();
}
});
}
ngAfterViewInit() {
for (let i=0; i<this.tables.length; i++) {
let table = this.tables[i];
table.dataSource.sort = this.sorts.toArray()[i];
table.dataSource.paginator = this.paginators.toArray()[i];
};
}
有人能看出我的错误吗?
您需要为每个“数据源”分配排序
所以,我想你想做一些像
this.tables.forEach((item,i)=>{
item.dataSource.sort=this.sort.find((_,index)=>index==i)
}
看看我们如何 select 使用 find((_x,index)
的 QueryList
重要提示:是
//see that is without ()
@ViewChildren(MatPaginator) paginators = new QueryList<MatPaginator>;
@ViewChildren(MatSort) sorts = new QueryList<MatSort>;
更新 有必要“给Angular时间”来绘制表格。我们可以在分配 matsort 时将其封闭到 setTimeout 中。
在stackblitz我用了一些像
dataSources:MatTableDataSource<any>[]=[]
@ViewChildren(MatSort) sorts:QueryList<MatSort>
ngOnInit()
{
service.getData().subscribe((res:any[])=>{
res.forEach((x,index)=>{
this.dataSources[index]=new MatTableDataSource(x)
})
setTimeout(()=>{
this.dataSources.forEach((x,index)=>{
x.sort=this.sorts.find((_,i)=>i==index)
})
})
})
}
Update2我不知道你的代码,所以你可以创建一个函数
setSorts()
{
setTimeout(()=>{
this.tables.forEach((item:any,index:number)=>{
const sort=this.sorts.find((_,i:number)=>i==index)
item.dataSource.sort=sort
})
})
}
注意:重要您的数据源应该是 MatTableDataSource,就是这样。如果你有一个数组,你应该写
table.dataSource=new MatTableDataSource<Row>(yourArray);
setTimeout 是必需的,因为当您向数组添加元素时仍然无法排序。您需要“等待”Angular 绘制表格。 setTimeout 对 Angular 说:“嗯!绘制表格,绘制完成后执行 setTimeout 下的函数。
并且总是调用你 add/remove 数组“this.tables”的一个元素(每次你制作 this.tables.push(..) 或 this.tables。删除)
关于 find((_x,index)=>.... 的使用,数组或 queryList 有方法:forEach、map、find.. 通常我们使用一个唯一的“参数”,例如`
myArray.forEach((x:any)=>{...x is the value of the element..}
但是所有这些方法都允许第二个参数,即元素的索引,例如
myArray.forEach((x:any,index:number)=>{
...x is the value of the element and index the position..
console.log(x,index)
}
当你使用“find”时,你可以得到“index”位置的元素,因为我们不需要变量的值,我通常使用_
(但你可以使用任何变量名
我有多个动态创建的 Angular table,每个都显示相同的列但具有不同的数据。我需要分别对每个 table 中的列进行排序。我目前有两个 table。当我点击第一个 header 列的箭头时,它排序正确。单击第二个 table 中的同一列没有任何反应。
这里是相关的html:
<div appMaterialElevation *ngFor="let item of tables; let i = index">
<table
mat-table
[dataSource]="item.dataSource"
multiTemplateDataRows
matSort
matSortActive="configName"
matSortDirection="asc"
>
<ng-container matColumnDef="configName">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Table Name</th>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
</div>
这是相关的TS:
import { Component, ViewChild, ViewChildren, QueryList, OnInit, AfterViewInit, OnDestroy } from '@angular/core';
export class Row {
configName: string;
}
export class FormatData {
formatName: string;
dataSource: MatTableDataSource<Row>;
selection: SelectionModel<Row>;
}
export class ConfigureFormatsComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChildren(MatPaginator) paginators = new QueryList<MatPaginator>();
@ViewChildren(MatSort) sorts = new QueryList<MatSort>();
tables: FormatData[];
displayedColumns: string[] = ['configName'];
getconfigformats() {
this.tables = [] as FormatData[];
this.myService.getMyData()
.subscribe((configList: MyConfigs[]) => {
let table = new FormatData();
let configNamesList = [] as Row[];
configList.forEach(config => {
let row = new Row();
row.configName = config.configName;
configNamesList.push(row);
});
table.dataSource = new MatTableDataSource<Row>(configNamesList);
table.selection = new SelectionModel<Row>(true, []);
this.tables.push(table);
this.ngAfterViewInit();
}
});
}
ngAfterViewInit() {
for (let i=0; i<this.tables.length; i++) {
let table = this.tables[i];
table.dataSource.sort = this.sorts.toArray()[i];
table.dataSource.paginator = this.paginators.toArray()[i];
};
}
有人能看出我的错误吗?
您需要为每个“数据源”分配排序
所以,我想你想做一些像
this.tables.forEach((item,i)=>{
item.dataSource.sort=this.sort.find((_,index)=>index==i)
}
看看我们如何 select 使用 find((_x,index)
重要提示:是
//see that is without ()
@ViewChildren(MatPaginator) paginators = new QueryList<MatPaginator>;
@ViewChildren(MatSort) sorts = new QueryList<MatSort>;
更新 有必要“给Angular时间”来绘制表格。我们可以在分配 matsort 时将其封闭到 setTimeout 中。
在stackblitz我用了一些像
dataSources:MatTableDataSource<any>[]=[]
@ViewChildren(MatSort) sorts:QueryList<MatSort>
ngOnInit()
{
service.getData().subscribe((res:any[])=>{
res.forEach((x,index)=>{
this.dataSources[index]=new MatTableDataSource(x)
})
setTimeout(()=>{
this.dataSources.forEach((x,index)=>{
x.sort=this.sorts.find((_,i)=>i==index)
})
})
})
}
Update2我不知道你的代码,所以你可以创建一个函数
setSorts()
{
setTimeout(()=>{
this.tables.forEach((item:any,index:number)=>{
const sort=this.sorts.find((_,i:number)=>i==index)
item.dataSource.sort=sort
})
})
}
注意:重要您的数据源应该是 MatTableDataSource,就是这样。如果你有一个数组,你应该写
table.dataSource=new MatTableDataSource<Row>(yourArray);
setTimeout 是必需的,因为当您向数组添加元素时仍然无法排序。您需要“等待”Angular 绘制表格。 setTimeout 对 Angular 说:“嗯!绘制表格,绘制完成后执行 setTimeout 下的函数。
并且总是调用你 add/remove 数组“this.tables”的一个元素(每次你制作 this.tables.push(..) 或 this.tables。删除)
关于 find((_x,index)=>.... 的使用,数组或 queryList 有方法:forEach、map、find.. 通常我们使用一个唯一的“参数”,例如`
myArray.forEach((x:any)=>{...x is the value of the element..}
但是所有这些方法都允许第二个参数,即元素的索引,例如
myArray.forEach((x:any,index:number)=>{
...x is the value of the element and index the position..
console.log(x,index)
}
当你使用“find”时,你可以得到“index”位置的元素,因为我们不需要变量的值,我通常使用_
(但你可以使用任何变量名