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 得到这个想法
我的数据源如下所示
[{"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 得到这个想法