如何使用角形材料在具有可扩展行的表中创建嵌套的垫子表

时间:2019-09-05 17:22:31

标签: angular angular-material

我有以下数据

[
    {
        "_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"
    }
]

如果"info.dependent": "parent"嵌套,则"info.dependent": "no_parent"没有子级。我试图创建一个动态表,但是我仍然坚持如何使其与嵌套表可折叠/可扩展。 这是我在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>

.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);
}

所需格式:-> nested table

嵌套格式如下

  

第1行-> _id,子域,域,信息。

当我们单击该特定行时,它必须展开并在具有列名和行数据的表中显示嵌套数据。

"nested": [
    {
        "domain": "aircraft",
        "_id": "c1859902",
        "info.mimetype": "image/jpeg",
        "info.dependent": "c9d5ab1a",
        "part_id": "c1859902",
        "subdomain": "tail"
    }
]

2 个答案:

答案 0 :(得分:4)

  

注意:对于那些想省略冗长解释的人,这里是StackBlitz example

您真正想要的是创建一个嵌套的VStack { Spacer() Text("FirstLine\nSecondLine\nThirdLine") .font(.headline) .lineLimit(2) Spacer() } ,其中所有嵌套表都是可排序的,并且也可以通过其过滤。

首先,由于需要在嵌套表中使用过滤和排序,因此需要为其创建新的mat-table。最初,您可以在MatTableDataSource中创建主dataSource,如下所示。

ngOnInit

从可扩展行example in the docs,我们可以看到如何创建可扩展行。在可展开的行中,我们现在将有一个表以及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); 输入。我们将添加一些条件,以便仅当存在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> 的用户摆脱悬停

这里是CSS,负责在悬停时添加addresses

background-color

因此,如果该行具有tr.example-element-row:not(.example-expanded-row):hover { background: #777; } ,则只需向该行添加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> 中,我们将定义单击模板中的一行时发生的逻辑。当用户单击此函数中的行时,我们还将实现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]); } 函数,以便可以过滤嵌套表。

applyFilter

这是StackBlitz上的一个有效示例。

答案 1 :(得分:0)

着眼于examples from the docs,尤其是the one with the expandable row

  • 您缺少multiTemplateDataRows中的<mat-table>指令
  • 缺少@detailExpand触发器
  • ...

Here是文档中包含您数据的示例

编辑(关于评论)

以下是获取动态列的方法:

将此添加到您的组件

  getKeys(object): string[] {
    return Object.keys(object);
  }

使用模板中的方法(根据随附的详细信息屏幕和nested键下有关多个元素的注释更新的模板):

<div class="example-element-descriptions">
    <div *ngFor="let nested of element['nested']"
         class="example-element-description">
        <div *ngIf="element['info.dependent'] === 'parent'">
            <div class="example-element-description__header">
                <div class="example-element-description__cell"
                     *ngFor="let key of getKeys(nested)">{{key}}</div>
            </div>
            <div class="example-element-description__content">
                <div class="example-element-description__cell"
                     *ngFor="let key of getKeys(nested)">{{element[key]}}
                </div>
            </div>
        </div>
        <div *ngIf="element['info.dependent'] === 'no_parent'">no parent</div>
    </div>
</div>