Dex*_*ter 11 html javascript typescript angular-material angular
我有以下数据
[
{
"_id": "c9d5ab1a",
"subdomain": "wing",
"domain": "aircraft",
"part_id": "c9d5ab1a",
"info.mimetype": "application/json",
"info.dependent": "parent",
"nested": [
{
"domain": "aircraft",
"_id": "c1859902",
"info.mimetype": "image/jpeg",
"info.dependent": "c9d5ab1a",
"part_id": "c1859902",
"subdomain": "tail"
}
]
},
{
"_id": "1b0b0a26",
"subdomain": "fuel",
"domain": "aircraft",
"part_id": "1b0b0a26",
"info.mimetype": "image/jpeg",
"info.dependent": "no_parent"
}
]
Run Code Online (Sandbox Code Playgroud)
这里 if "info.dependent": "parent"then 它是嵌套的,如果"info.dependent": "no_parent"then 它没有孩子。我试图创建一个动态表,但我被困在如何使用嵌套表使其可折叠/可扩展。这是我在stackblitz 上的代码。
<mat-table class=" mat-elevation-z8" [dataSource]="dataSource">
<ng-container [matColumnDef]="col" *ngFor="let col of displayedColumns">
<mat-header-cell *matHeaderCellDef> {{ col }} </mat-header-cell>
<mat-cell *matCellDef="let element"> {{ element[col] }} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row;columns:displayedColumns"></mat-row>
</mat-table>
Run Code Online (Sandbox Code Playgroud)
.ts
public data = [
{
"_id": "c9d5ab1a",
"subdomain": "wing",
"domain": "aircraft",
"part_id": "c9d5ab1a",
"info.mimetype": "application/json",
"info.dependent": "parent",
"nested": [
{
"domain": "aircraft",
"_id": "c1859902",
"info.mimetype": "image/jpeg",
"info.dependent": "c9d5ab1a",
"part_id": "c1859902",
"subdomain": "tail"
}
]
},
{
"_id": "1b0b0a26",
"subdomain": "fuel",
"domain": "aircraft",
"part_id": "1b0b0a26",
"info.mimetype": "image/jpeg",
"info.dependent": "no_parent"
}
];
dataSource = new MatTableDataSource([]);
displayedColumns = ['_id', 'subdomain', 'domain', 'part_id', 'info.mimetype', 'info.dependent'];
constructor(){
this.displayedColumns = this.displayedColumns;
this.dataSource = new MatTableDataSource(this.data);
}
Run Code Online (Sandbox Code Playgroud)
嵌套格式如下
第 1 行 --> _id ,subdomain,domain,info.dependent
当我们单击该特定行时,它必须展开并在带有列名和行数据的表中显示嵌套数据。
"nested": [
{
"domain": "aircraft",
"_id": "c1859902",
"info.mimetype": "image/jpeg",
"info.dependent": "c9d5ab1a",
"part_id": "c1859902",
"subdomain": "tail"
}
]
Run Code Online (Sandbox Code Playgroud)
nas*_*h11 25
注意:对于那些想跳过冗长解释的人,这里是StackBlitz 示例。
您真正想要的是创建一个嵌套mat-table,其中所有嵌套表都可以排序并且也可以过滤。
首先,由于您需要在嵌套表中使用过滤和排序,您需要MatTableDataSource为它创建一个新的。这可以在创建主最初做dataSource的ngOnInit像下面。
usersData: User[] = [];
USERS.forEach(user => {
if (user.addresses && Array.isArray(user.addresses) && user.addresses.length) {
this.usersData = [...this.usersData, { ...user, addresses: new MatTableDataSource(user.addresses) }];
} else {
this.usersData = [...this.usersData, user];
}
});
this.dataSource = new MatTableDataSource(this.usersData);
Run Code Online (Sandbox Code Playgroud)
从文档中的可扩展行示例中,我们可以看到如何创建可扩展行。在可扩展行中,我们现在将有一个表格和Filter输入。我们将添加一些条件,以便该行仅在存在时才可扩展addresses。
<div class="example-element-detail" *ngIf="element.addresses?.data.length"
[@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
<div class="inner-table mat-elevation-z8" *ngIf="expandedElement">
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
<table #innerTables mat-table #innerSort="matSort" [dataSource]="element.addresses" matSort>
<ng-container matColumnDef="{{innerColumn}}" *ngFor="let innerColumn of innerDisplayedColumns">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{innerColumn}} </th>
<td mat-cell *matCellDef="let element"> {{element[innerColumn]}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="innerDisplayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: innerDisplayedColumns;"></tr>
</table>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
既然只有在有嵌套元素时行才会扩展,我们需要为没有嵌套元素的用户摆脱悬停 addresses
这是负责添加background-color悬停的 CSS
tr.example-element-row:not(.example-expanded-row):hover {
background: #777;
}
Run Code Online (Sandbox Code Playgroud)
因此,example-element-row如果行有一个address. 如果它没有地址,则该行不应该是可点击的,并且不应该有一个悬停来向用户表明该行实际上是不可点击的。
<tr mat-row *matRowDef="let element; columns: columnsToDisplay;"
[class.example-element-row]="element.addresses?.data.length"
[class.example-expanded-row]="expandedElement === element"
(click)="toggleRow(element)">
</tr>
Run Code Online (Sandbox Code Playgroud)
在 中toggleRow,我们将定义当您单击模板中的一行时发生的情况的逻辑。我们还将sort在用户单击该行时实现此功能。
@ViewChildren('innerSort') innerSort: QueryList<MatSort>;
toggleRow(element: User) {
element.addresses && (element.addresses as MatTableDataSource<Address>).data.length ? (this.expandedElement = this.expandedElement === element ? null : element) : null;
this.cd.detectChanges();
this.innerTables.forEach((table, index) => (table.dataSource as MatTableDataSource<Address>).sort = this.innerSort.toArray()[index]);
}
Run Code Online (Sandbox Code Playgroud)
最后,我们需要定义applyFilter函数以便过滤嵌套表。
@ViewChildren('innerTables') innerTables: QueryList<MatTable<Address>>;
applyFilter(filterValue: string) {
this.innerTables.forEach((table, index) => (table.dataSource as MatTableDataSource<Address>).filter = filterValue.trim().toLowerCase());
}
Run Code Online (Sandbox Code Playgroud)
这是StackBlitz上的一个工作示例。
| 归档时间: |
|
| 查看次数: |
27320 次 |
| 最近记录: |