在 Angular 中为动态 mat-table 创建一个通用管道

问题描述

我有一个 Angular 前端,它当前从 REST API 接收数据并将其显示在表格中。接收到的数据由三种不同的类型组成:字符串、日期和数字(int 和 float)。 由于有多个数据列,我想为不同类型的接收到的 JSON 创建单个表模板,我应该动态创建 mat-table:

 <table mat-table [dataSource]="dataSource" class="mat-elevation-z2" matSort matSortActive="sysTime"
        matSortDirection="desc" matSortdisableClear>
       
        <ng-container *ngFor="let column of colDefs" [matColumnDef]="column.name">
            <th mat-header-cell *matHeaderCellDef mat-sort-header [hidden]="column.settings.hidden"
                (auxclick)="onHeaderClick($event,column)"> {{column.settings.alias}}
            </th>
            <td mat-cell *matCellDef="let element" [hidden]="column.settings.hidden"
                (click)="onRowClick(column.name,element)"> {{element[column.name] | generalPipe }} </td>
        </ng-container>
 <tr mat-header-row *matHeaderRowDef="dataSource.columns$ | async; sticky:true; "></tr>
        <tr mat-row *matRowDef="let row; columns: dataSource.columns$ | async;"></tr>
    </table>

主要问题是一些数字被表示为字符串。这是后端的东西,我无法改变它。为了正确对列进行排序,我必须将它们转换为数字。

因此我应该有一个通用管道来分别格式化数字、字符串和日期:

@Pipe({
    name: "generalPipe",pure: true
})
export class GeneralPipe implements PipeTransform {

    constructor() { }

    format = new DatePipe('en-US');
    intReg: RegExp = /^\d{1,10}$/;
    floatRef: RegExp = /^\d{1,4}\.\d{1,6}$/;
    public transform(value: any): any {

        if (Date.parse(value)) {

            return this.format.transform(value,'dd/MM/yy HH:mm:ss');
        }

        if (typeof value === 'string') {
            if (this.intReg.test(value)) return parseInt(value);
            else if (this.floatRef.test(value)) return parseFloat(value);
        }
        return (value);

    }

}

数字格式有效,但 日期 类型评估无法正常工作。在某些系统中,它将数值解析为 Unix 纪元,而在某些系统中仅格式化日期值。

我也试过检查 (value instanceof Date) 但还是不行。

我该如何解决这个问题?

示例 JSON:

价值
系统时间 “2020-11-29T21:33:51”
数量 “3435”
发生时间 “2040-12-12T12:56:13”
状态 1
版本 “1”
蝙蝠 80
纬度 1.398401
经度 1.774052

解决方法

作为一种解决方法,我添加了另一个 RegEx:

dateReg: RegExp = /^20\d{2}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}$/;

然后:

public transform(value: any): any {

        if (typeof value === 'string') {

            if (this.intReg.test(value)) return parseInt(value);
            else if (this.floatReg.test(value)) return parseFloat(value);
            else if (this.dateReg.test(value)) return this.dateFormat.transform(value,'dd/MM/yy HH:mm:ss');
        }
        return (value);

    }

但我仍然不知道如何检测日期类型。