Angular Material 循环数据时的行

Angular Material Row when looping through data

我的数据源如下所示

[{"isGroup":true,"groupName":"MV Reddy","items":[{"id":1,"name":"MV Reddy","verticalid":5,"vertical":"Colocation - Large > 20 Racks","target":"150","sap":"80","colo":"20","others":"50","quarter":1,"year":2019},{"id":10,"name":"MV Reddy","verticalid":6,"vertical":"Govt","target":"150","sap":"80","colo":"20","others":"50","quarter":1,"year":2020}]},{"isGroup":true,"groupName":"Neeraj Jha","items":[{"id":2,"name":"Neeraj Jha","verticalid":4,"vertical":"Alliances","target":"70","sap":"20","colo":"30","others":"20","quarter":2,"year":2019},{"id":5,"name":"Neeraj Jha","verticalid":4,"vertical":"Alliances","target":"150","sap":"80","colo":"20","others":"50","quarter":1,"year":2019}]},{"isGroup":false,"groupName":"Suresh Rathod","items":[{"id":3,"name":"Suresh Rathod","verticalid":3,"vertical":"C4C India (Public Cloud)","target":"100","sap":"20","colo":"30","others":"50","quarter":1,"year":2019}]},{"isGroup":false,"groupName":"Arun Dubey","items":[{"id":4,"name":"Arun Dubey","verticalid":6,"vertical":"Govt","target":"150","sap":"80","colo":"20","others":"50","quarter":4,"year":2019}]},{"isGroup":true,"groupName":"Atin Singh","items":[{"id":6,"name":"Atin Singh","verticalid":5,"vertical":"Colocation - Large > 20 Racks","target":"150","sap":"80","colo":"20","others":"50","quarter":1,"year":2020},{"id":7,"name":"Atin Singh","verticalid":2,"vertical":"IAAS and Rest of Ctrls Services","target":"150","sap":"80","colo":"20","others":"50","quarter":1,"year":2020},{"id":8,"name":"Atin Singh","verticalid":3,"vertical":"C4C India (Public Cloud)","target":"150","sap":"80","colo":"20","others":"50","quarter":1,"year":2020},{"id":9,"name":"Atin Singh","verticalid":6,"vertical":"Govt","target":"150","sap":"80","colo":"20","others":"50","quarter":1,"year":2020}]}]

我 wrote/printing 我的 Table 是这样的:

<table class="mat-elevation-z8 " mat-table matSort [dataSource]='targetData' (matSortChange)="sortData($event)">
    <ng-container matColumnDef="Employee">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> Employee </th>
        <td mat-cell *matCellDef="let element"> {{element.items[0].name}}
        </td>
    </ng-container>

    <ng-container matColumnDef="groupData">

        <ng-container *matCellDef="let group">
            <ng-container *ngFor="let groupCol of group.items;index as i;">
                <ng-container *ngIf="i==0 else newRow;">
                    <td mat-cell rowspan="group.items.length">
                        {{group.groupName}}
                    </td>
                    <td mat-cell>
                        {{groupCol.vertical}}
                    </td>
                    <td mat-cell>
                        {{groupCol.target}}
                    </td>
                    <td mat-cell>
                        {{groupCol.sap}}
                    </td>
                    <td mat-cell>
                        {{groupCol.colo}}
                    </td>
                    <td mat-cell>
                        {{groupCol.others}}
                    </td>
                </ng-container>
                <ng-template #newRow>
                    <tr mat-row>
                        <td mat-cell>
                            {{groupCol.vertical}}
                        </td>
                        <td mat-cell>
                            {{groupCol.target}}
                        </td>
                        <td mat-cell>
                            {{groupCol.sap}}
                        </td>
                        <td mat-cell>
                            {{groupCol.colo}}
                        </td>
                        <td mat-cell>
                            {{groupCol.others}}
                        </td>
                    </tr>
                </ng-template>

            </ng-container>
        </ng-container>

    </ng-container>

    <ng-container matColumnDef="Vertical">
        <th mat-header-cell *matHeaderCellDef>Vertical</th>
        <td mat-cell *matCellDef="let element"> {{element.items[0].vertical}} </td>
    </ng-container>
    <ng-container matColumnDef="Target">
        <th mat-header-cell *matHeaderCellDef>Target</th>
        <td mat-cell *matCellDef="let element"> {{element.items[0].target}} </td>
    </ng-container>
    <ng-container matColumnDef="SAP">
        <th mat-header-cell *matHeaderCellDef>SAP</th>
        <td mat-cell *matCellDef="let element">{{element.items[0].sap}}</td>
    </ng-container>
    <ng-container matColumnDef="COLO">
        <th mat-header-cell *matHeaderCellDef>COLO</th>
        <td mat-cell *matCellDef="let element">{{element.items[0].colo}}</td>
    </ng-container>
    <ng-container matColumnDef="Others">
        <th mat-header-cell *matHeaderCellDef>Others</th>
        <td mat-cell *matCellDef="let element">{{element.items[0].others}}</td>
    </ng-container>
    <ng-container matColumnDef="Action">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> Action </th>
        <td mat-cell *matCellDef="let element">
            <div class="tableActions ">

                <button class="view mat-button" (click)='edit(element.items[0])'>
                    <i class="material-icons">
                        create
                    </i>
                </button>
            </div>
        </td>
    </ng-container>
    <tr mat-header-row *matHeaderRowDef="TargetTable;"></tr>
    <tr mat-row *matRowDef="let row; columns: TargetTable;"></tr>
    <tr mat-row *matRowDef="let row; columns: ['groupData']; when: isAGroup"></tr>
</table>

我在遍历数据时无法在 table 中打印另一行

最终结果应该如下所示。

您的方法是正确的,因为您正在使用 rowspan 属性。然而,模板不必要的复杂,如果您预处理数据可以简化它。

我在开源项目Koia using a RowSpanComputer class. Within summary-table.component.html中解决了一个类似的问题,然后使用计算的行跨度来定义td元素的rowspan属性。

[attr.rowspan]="rowSpans[iCol][iRow].span"

RowSpanComputer class 为指定的 table 数据(行数组)中的每个单元格计算 rowspan。它基本上遍历行并增加 rowspan 的单元格,只要它们的值保持不变并且左侧定位的单元格也被跨越。一旦值发生变化,相应的 rowspan 就会重置为零。

请查看以下使用您提供的数据的 StackBlitz。这显然必须进一步完善才能获得您期望的结果。

更新

如果您希望 rowspan 应用于单元格,即使左侧定位的单元格未被跨越,只需从 RowSpanComputer class.

中删除以下行
spanColumnContexts.slice(iCol + 1).forEach(c => c.spannedRow = {}); 

我在 StackBlitz 中这样做了,其中将 RowSpanComputer 重命名为 GroupingRowSpanComputer 以避免混淆。

我的Table:

<table mat-table matSort [dataSource]="targetData" class="mat-elevation-z8">

    <ng-container matColumnDef="Employee">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> Employee </th>
        <td mat-cell *matCellDef="let element" [attr.rowspan]="rowSpanLength(element)"
            [style.display]="rowSpanLength(element)>0 ? ''  : 'none'">
            {{element.name}}
        </td>
    </ng-container>
    <ng-container matColumnDef="Vertical">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> Vertical </th>
        <td mat-cell *matCellDef="let element"> {{element.vertical}}
        </td>
    </ng-container>
    <ng-container matColumnDef="Target">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> Target </th>
        <td mat-cell *matCellDef="let element"> {{element.target}}
        </td>
    </ng-container>
    <ng-container matColumnDef="SAP">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> SAP </th>
        <td mat-cell *matCellDef="let element"> {{element.sap}}
        </td>
    </ng-container>
    <ng-container matColumnDef="COLO">
        <th mat-header-cell *matHeaderCellDef mat-sort-header> COLO </th>
        <td mat-cell *matCellDef="let element"> {{element.colo}}
        </td>
    </ng-container>
    <ng-container matColumnDef="Others">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Others</th>
        <td mat-cell *matCellDef="let element"> {{element.others}}
        </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="TargetTableColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: TargetTableColumns"></tr>
</table>

我的 rowSpanLength 函数如下所示:

rowSpanLength(item) {
    let nameArr = this.targetData.filter(i => i.name === item.name);
    //return length if the item is first element in above array else 0
    return nameArr[0].id === item.id ? nameArr.length : 0;
}

如果 item/tr 是组中的第一个,此函数将保留 rowSpan,对于其余所有项目,名称 td 将被隐藏。

结果如下,这就是我想要的。从@uminder (https://whosebug.com/users/2358409/uminder) stackblitz 得到这个想法