Angular-Material表格表尾合计的正确用法

785 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

三个月前

三个月前遇到了表格需要在表尾设置一个冻结行显示合计的需求,通过翻阅文档,当时的写法是这样的:(所有说明和介绍均留在下方《正确用法》中)

网页部分:

<table 
    mat-table 
    class="tableData" 
    [dataSource]="skuData" 
    matSort 
    matSortDisableClear matSortDirection="asc"
    [@animateStagger]="{value:'50'}">
    <ng-container matColumnDef="id">
        <th mat-header-cell *matHeaderCellDef>序号</th>
        <td mat-cell *matCellDef="let row">{{ row.no }}</td>
        <td mat-footer-cell *matFooterCellDef> 合计 </td>
    </ng-container>
    ……
    <ng-container matColumnDef="total_weight">
        <th mat-header-cell *matHeaderCellDef>产品总重</th>
        <td mat-cell *matCellDef="let row">{{ row.total_weight | number:"0.2" }}</td>
        <td mat-footer-cell *matFooterCellDef> {{ getTotalTotalWeight() | number:"0.2" }} </td>
    </ng-container>
<!-- 表尾 -->
    <tr mat-header-row *matHeaderRowDef="skuDataColumns; sticky:true"></tr>
    <tr mat-row *matRowDef="let row; columns: skuDataColumns;" class="product" matRipple></tr>
    <tr mat-footer-row *matFooterRowDef="skuDataColumns"></tr>
</table>

ts部分:

getTotalPlanQty(): number {
    return this.general.getTotal(this.skuData, 'plan_qty')
  }
  getTotalFactQty() {
    return this.general.getTotal(this.skuData, 'fact_qty')
  }
  getTotalPlanWeight() {
    return this.general.getTotal(this.skuData, 'plan_weight')
  }
getTotalTotalWeight() {
    return this.general.getTotal(this.skuData, 'total_weight')
  }

由于只有四列求和,当时第一次用也没觉得有什么问题。
直到我今天碰到一个需要求和五列合计的表格,发现原来的写法也太过繁杂了,于是稍微重构优化一下,顺便总结一下正确用法。

正确用法

ts部分

获取表格的数据:

fetchTableInfo(): void {
    const url = `transport/detail/${this.planId}`;
    this.confSvc.sendGetCatch(url, this.isLoading).subscribe(res => {
      // 表格数据
      this.skuData = res['data'].sku_data || [];
      this.confSvc.changeLoading(false);
    });
  }

分析数据结构:(以下均为测试数据)

skuData=[
  {
    "other_price": "0.00",
    "tax_price": "0.00",
    "first_freight_price": "0.00",
    ……
    "plan_weight": "0",
    "plan_total_weight": "0",
    "no": 1
  },
  {
    "other_price": "0.00",
    "tax_price": "0.00",
    "first_freight_price": "0.00",
    ……
    "plan_weight": "0",
    "plan_total_weight": "0",
    "no": 2
  }
]

求和公共函数

其中Array为数据数组,key为数组中对应的数据字段
该数组的作用为:根据key值对数组Array中为字段为key的值进行求和并返回

// 放入数组,及数组对应的键值
    getTotal(Array, key: string): number {
        // 初始化总和
        let tempOrderQty = 0;
        // 循环求值
        Array.forEach(value => {
            tempOrderQty += toInteger(value[key]);
        });
        // 返回总值
        return tempOrderQty;
    }

求和时调用:

getTotalQty(Index: string): number {
    return this.general.getTotal(this.skuData, Index);
  }

html部分

<table 
    mat-table 
    class="tableData" 
    [dataSource]="skuData"
    matSort matSortDisableClear 
    matSortDirection="asc"
    [@animateStagger]="{value:'50'}">
    <ng-container matColumnDef="id">
        <th mat-header-cell *matHeaderCellDef>序号</th>
        <td mat-cell *matCellDef="let row">{{ row.no }}</td>
        <td mat-footer-cell *matFooterCellDef>合计</td>
    </ng-container>
     ……
    <ng-container matColumnDef="product_total_price">
        <th mat-header-cell *matHeaderCellDef>产品总价</th>
        <td mat-cell *matCellDef="let row">{{ row.product_total_price }}</td>
        <td mat-footer-cell *matFooterCellDef> {{ getTotalQty('product_total_price') | number:"0.0-2" }} </td>
    </ng-container>
    <ng-container matColumnDef="other_price">
        <th mat-header-cell *matHeaderCellDef>其他费用单价</th>
        <td mat-cell *matCellDef="let row">{{ row.other_price }}</td>
        <td mat-footer-cell *matFooterCellDef>-</td>
    </ng-container>
    <!-- 表尾 -->
    <tr mat-header-row *matHeaderRowDef="skuDataColumns; sticky:true"></tr>
    <tr mat-row *matRowDef="let row; columns: skuDataColumns;" class="product" matRipple></tr>
    <tr mat-footer-row *matFooterRowDef="skuDataColumns"></tr>
</table>

注意即使不求和,该列的ng-container内也需要加上(此处用-代替,也可以为空)

<td mat-footer-cell *matFooterCellDef>-</td>

求和列的ng-container部分则需要加上

<td mat-footer-cell *matFooterCellDef> {{ getTotalQty('product_total_price') | number:"0.0-2" }} </td>

其中getTotalQty为求和函数,参数'product_total_price'为数组中需要求和的字段名称
注意不要写成row.product_total_price的格式,因为row.product_total_price会传具体的数值

| number:"0.0-2" 为number管道,用于设置数字的显示 ,用法如下

number管道用来将数字处理为需要的小数格式

接收的参数格式为:{最少整数位数}.{最少小数位数}-{最多小数位数}

  1. 其中最少整数位数默认为1
  2. 最少小数位数默认为0
  3. 最多小数位数默认为3
  4. 当小数位数少于规定的{最少小数位数}时,会自动补0
  5. 当小数位数多于规定的{最多小数位数}时,会四舍五入

转载自:www.jianshu.com/p/23543d9d1…

最后在表尾加上

<tr mat-footer-row *matFooterRowDef="skuDataColumns"></tr>
<!-- skuDataColumns为行模板定义 -->

代码看着舒服多了!收工!