Angular Material mat 表合并的行

Posted

技术标签:

【中文标题】Angular Material mat 表合并的行【英文标题】:Angular Material mat table merged rows 【发布时间】:2021-01-03 07:42:28 【问题描述】:

我正在努力解决以下问题。我想将我的基本 html 表更改为 mat-table。 但我找不到合并前两列的两行的方法。

我在顶部有 mat-table,在底部有基本的 html 表格:

[![在此处输入图片描述][1]][1]

我想要的垫子表如下: 对于每个参考 + 发票,我想要两行,一排带有发票,另一排带有预期,就像在我的底部表格中一样。

我的基本html表格如下:

<table>
  <thead>
    <th *ngFor= "let column of headersContainers">
      column
    </th>
  </thead>

  <tbody *ngFor = "let container of completeContainers">
    <th rowspan = "2" >container.containerReference</th>
    <th rowspan = "2" >container.invoiceReference</th>
      <td>Invoiced</td>
      <td>container.InvoicedCosts.OFC | currency :'€ '</td>
      <td>container.InvoicedCosts.THC | currency :'€ '</td>
      <td>container.InvoicedCosts.BAF | currency :'€ '</td>
      <td>container.InvoicedCosts.Total | currency :'€ '</td>
    <tr> 
      <td>Expected</td> 
      <td>container.ExpectedCosts.OFC | currency :'€ '</td>
      <td>container.ExpectedCosts.THC | currency :'€ '</td>
      <td>container.ExpectedCosts.BAF | currency :'€ '</td>
      <td>container.ExpectedCosts.Total | currency :'€ '</td>
    </tr>
  </tbody>
</table>

而我的 mat-table html 如下:

<table mat-table [dataSource]="dataSource">

  <ng-container matColumnDef="containerReference">
    <th mat-header-cell *matHeaderCellDef [rowSpan]="2"> Reference </th>
    <td mat-cell *matCellDef="let container"> container.containerReference </td>
  </ng-container>

  <ng-container matColumnDef="InvoiceReference">
    <th mat-header-cell *matHeaderCellDef [rowSpan]="2"> Invoice </th>
    <td mat-cell *matCellDef="let container"> container.invoiceReference </td>
  </ng-container>

  <ng-container matColumnDef="InvoicedOrExpected">
    <th mat-header-cell *matHeaderCellDef> Invoiced or expected </th>
    <td mat-cell *matCellDef="let container"> Invoiced </td>
  </ng-container>

  <ng-container matColumnDef="OHC">
    <th mat-header-cell *matHeaderCellDef> Ocean handling costs </th>
    <td mat-cell *matCellDef="let container"> container.OHC </td>
  </ng-container>

  <ng-container matColumnDef="THC">
    <th mat-header-cell *matHeaderCellDef> Terminal handling costs </th>
    <td mat-cell *matCellDef="let container"> container.THC </td>
  </ng-container>

  <ng-container matColumnDef="BAF">
    <th mat-header-cell *matHeaderCellDef> Bunker adjustment factor </th>
    <td mat-cell *matCellDef="let container"> container.BAF </td>
  </ng-container>

  <ng-container matColumnDef="Total">
    <th mat-header-cell *matHeaderCellDef> Total </th>
    <td mat-cell *matCellDef="let container"> container.Total </td>
  </ng-container>

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

</table>

我的数据源如下:

[
    
        "containerReference": "20DV HLXU1234567",
        "invoiceReference": "109554 (20000678)",
        "InvoicedCosts": 
            "OFC": 1023.0,
            "THC": 100.0,
            "BAF": 67.0,
            "Total": 1190.0
        ,
        "ExpectedCosts": 
            "OFC": 465.0,
            "THC": 205.0,
            "BAF": 285.0,
            "Total": 955.0
        
    ,
    
        "containerReference": "20DV HLXU2234567",
        "invoiceReference": "109554 (20000678)",
        "InvoicedCosts": 
            "OFC": 3445.0,
            "THC": 65.0,
            "BAF": 77.0,
            "Total": 3587.0
        ,
        "ExpectedCosts": 
            "OFC": 465.0,
            "THC": 205.0,
            "BAF": 285.0,
            "Total": 955.0
        
    
]

请注意,由于我在 java 中使用 ArrayNode,因此我可以更改数据源设置。

编辑:

我已将 HTML 文件更改为:

<h1>Costs per container</h1>
<mat-checkbox (change)="switchEvent($event)" labelPosition ="before">Show correctly invoiced containers</mat-checkbox>

<table mat-table [dataSource]="dataSource">

  <!--Container reference-->
  <ng-container matColumnDef="containerReference">
    <th mat-header-cell *matHeaderCellDef> Reference </th>
    <td mat-cell *matCellDef="let container"> container.containerReference </td>
  </ng-container>

  <!--Invoice reference-->
  <ng-container matColumnDef="invoiceReference">
    <th mat-header-cell *matHeaderCellDef> Invoice </th>
    <td mat-cell *matCellDef="let container"> container.invoiceReference </td>
  </ng-container>

  <!--Invoiced columns-->
  <ng-container matColumnDef="invoicedOHC">
    <th mat-header-cell *matHeaderCellDef> Ocean handling costs </th>
    <td mat-cell *matCellDef="let container"> container.InvoicedCosts.OFC </td>
  </ng-container>

  <ng-container matColumnDef="invoicedTHC">
    <th mat-header-cell *matHeaderCellDef> Terminal handling costs </th>
    <td mat-cell *matCellDef="let container"> container.InvoicedCosts.THC </td>
  </ng-container>

  <ng-container matColumnDef="invoicedBAF">
    <th mat-header-cell *matHeaderCellDef> Bunker adjustment factor </th>
    <td mat-cell *matCellDef="let container"> container.InvoicedCosts.BAF </td>
  </ng-container>

  <ng-container matColumnDef="invoicedTotal">
    <th mat-header-cell *matHeaderCellDef> Total </th>
    <td mat-cell *matCellDef="let container"> container.InvoicedCosts.Total </td>
  </ng-container>

  <!--expected columns-->
  <ng-container matColumnDef="expectedOHC">
    <th mat-header-cell *matHeaderCellDef></th>
    <td mat-cell *matCellDef="let container"> container.ExpectedCosts.OFC </td>
  </ng-container>

  <ng-container matColumnDef="expectedTHC">
    <th mat-header-cell *matHeaderCellDef></th>
    <td mat-cell *matCellDef="let container"> container.ExpectedCosts.THC </td>
  </ng-container>

  <ng-container matColumnDef="expectedBAF">
    <th mat-header-cell *matHeaderCellDef></th>
    <td mat-cell *matCellDef="let container"> container.ExpectedCosts.BAF </td>
  </ng-container>

  <ng-container matColumnDef="expectedTotal">
    <th mat-header-cell *matHeaderCellDef></th>
    <td mat-cell *matCellDef="let container"> container.ExpectedCosts.Total </td>
  </ng-container>

  <!--Invoiced or expected columns-->
  <ng-container matColumnDef="invoicedLabel">
    <th mat-header-cell *matHeaderCellDef> Invoiced or expected </th>
    <td mat-cell *matCellDef="let container"> Invoiced </td>
  </ng-container>

  <ng-container matColumnDef="expectedLabel">
    <th mat-header-cell *matHeaderCellDef></th>
    <td mat-cell *matCellDef="let container"> Expected </td>
  </ng-container>

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

</table>

SCSS如下:

table 
  width: 100%;


.mat-column-containerReference grid-area: containerReference;
.mat-column-invoiceReference grid-area: invoiceReference;
.mat-column-invoicedOHC grid-area: invoicedOHC;
.mat-column-invoicedTHC grid-area: invoicedTHC;
.mat-column-invoicedBAF grid-area: invoicedBAF;
.mat-column-invoicedTotal grid-area: invoicedTotal;
.mat-column-expectedOHC grid-area: expectedOHC;
.mat-column-expectedTHC grid-area: expectedTHC;
.mat-column-expectedBAF grid-area: expectedBAF;
.mat-column-expectedTotal grid-area: expectedTotal;
.mat-column-expected grid-area: expected;
.mat-column-invoiced grid-area: invoiced;
.mat-column-invoicedLabel grid-area: invoicedLabel;
.mat-column-expectedLabel grid-area: expectedLabel;

tr 
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-areas: 
            "containerReference invoiceReference invoicedLabel invoicedOHC invoicedTHC invoicedBAF invoicedTotal"
            "containerReference invoiceReference expectedLabel expectedOHC expectedTHC expectedBAF expectedTotal";


tr.mat-header-row 
  grid-template-areas: 
        "containerReference invoiceReference invoicedLabel invoicedOHC invoicedTHC invoicedBAF invoicedTotal";
  
  .mat-column-expected,
  .mat-column-expectedLabel 
    display: none;
  


td, th 
  display: flex;
  align-items: center;
  padding-left: 5px !important;
  border-right: 1px solid rgba(128, 128, 128, .4);

这会产生我想要的合并行,但列与行不对齐:

[![在此处输入图片描述][2]][2]

编辑 2:

在RobbieAreBest的评论之后,我将scss部分grid-template-columns: repeat(4, 1fr);改为grid-template-columns: repeat(7, 1fr);

这给了我以下结果: [![在此处输入图片描述][3]][3]

或者,它看起来仍然不完美。如果有人知道如何使细胞对齐,那就太好了! [1]:https://i.stack.imgur.com/JzP51.png [2]:https://i.stack.imgur.com/fnut4.png [3]:https://i.stack.imgur.com/Vx7cK.png

【问题讨论】:

【参考方案1】:

我认为这对于 CSS 网格来说是一个很好的例子。在您的模板中,我根本不用担心 rowSpan,只需将所有数据放入其自己的列中(对于 Invoiced 和 Expected 值有单独的列)。

tr 标记的规则添加到display:grid 并根据需要定义grid-template-columns。然后,您可以将grid-area 应用于每一列,并使用grid-template-areas 规则定义您的“行跨度”。

如果您希望标题以不同方式显示,您还可以为tr.mat-header-row 定义一组不同的grid-template-areas 规则。

我设计了一个小例子,它应该有一个类似于您正在寻找的解决方案: https://stackblitz.com/edit/angular-u2b8qa?file=src/app/table-basic-example.scss

【讨论】:

感谢您的回复,结果几乎如我所愿。我已经编辑了我的问题,也许你可以帮忙解决最后一点! 你只需要改变 grid-template-columns: repeat(4, 1fr);到网格模板列:重复(7、1fr);因为你有 7 列。如果您愿意,您还可以为列定义不同的大小。 啊,谢谢。我对css不熟悉,所以这对我很有帮助。这张桌子看起来还不是它应该的样子,但它比原来的要好。 太棒了,我很高兴你的方向是正确的。您可能还想尝试将 .mat-column-expectedOHC、.mat-column-expectedTHC、.mat-column-expectedBAF 和 .mat-column-expectedTotal 添加到 display:none 规则中 tr.mat-h​​eader-row

以上是关于Angular Material mat 表合并的行的主要内容,如果未能解决你的问题,请参考以下文章

Angular Material 2:多个 mat-table 排序仅适用于第一个表

Angular Material 表动态列

Angular Material - 垫表排序行

Angular 6 Material - 等待 Mat 对话框关闭

Angular 5 / Material,如何在 Mat Dialog 中删除垂直滚动?

Angular Material Elements 不会对更改做出反应