带有动态复选框的 CDK Angular Table 找不到正确的列名称

CDK Angular Table with dynamic checkboxes not finding correct column names

我有一个动态 CDK Angular Material mat-table,我已经修复了 mat-checkbox。它正在填充数据,但不允许我设置正确的列 headers。显示的所有内容都来自 UserInformation 数组的 key:value 对。但是,我需要设置第二个数组来显示正确的 header 名称,因为我无法控制来自 API 的键名,需要在 TypeScript 中设置它们。并非所有来自 API 的信息都会显示在 table 中。我也会有多个 tables 并且需要使它完全可重用到显示内容将在 TypeScript 中更改的位置,其他所有内容都将被注入。

现在我只想让显示的列名称在 table 中正确显示。

//Dummy Data
const UserInformation: any[] = [
  {
    'firstName': 'Jane',
    'lastName': 'Doe',
    'jobRole': 'My Job',
    'company': 'Work',
    'status': true,
    'employeeID': '23456',
    'phone': '(253)227-2567',
    'email': 'myemail@myemail.com'
  },
  {
    'firstName': 'John',
    'lastName': 'Smith',
    'jobRole': 'My Job',
    'company': 'Work',
    'status': true,
    'employeeID': '23456',
    'phone': '(253)227-2567',
    'email': 'myemail@myemail.com'
  }
];

columns: any;

// Material Table Columns
  @Input() public content: any;

  public rows = new MatTableDataSource<any>();
  headers = [
      { filed: '',
      },
      { field: 'firstName',
        title: 'First Name',
        cell: (element: any) => `${element.firstName}`,
      },
      { field: 'lastName',
        title: 'Last Name',
        cell: (element: any) => `${element.lastName}`,
      },
      { field: 'employeeID',
        title: 'Employee ID',
        cell: (element: any) => `${element.employeeID}`,
      },
      { field: 'jobRole',
        title: 'Job Role',
        cell: (element: any) => `${element.jobRole}`,
      },
      { field: 'email',
        title: 'Email',
        cell: (element: any) => `${element.email}`,
      }
    ];
    displayedColumns = this.headers.map(c => c.field);
    public selection = new SelectionModel<any>(true, []);

// Material Table Functionality
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;
  @ViewChild('tableResults') tableResults;

  this.showUsers();

// Material Table
  public filterBy(event: any): void {
    const filterBy: string = event.target.value;
    this.rows.filter = filterBy;
  }

  public isAllSelected() {
    const numSelected = this.selection.selected.length;
    const numRows = this.rows.data.length;
    return numSelected === numRows;
  }

  public masterToggle() {
    this.isAllSelected() ?
      this.selection.clear() :
      this.rows.data.forEach(row => this.selection.select(row));
  }

  public checkboxLabel(row?: any): string {
    return (!row)
      ? `${this.isAllSelected() ? 'select' : 'deselect'} all`
      : `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;
  }

  private updateRows(): void {
    this.rows = new MatTableDataSource<any>(this.displayedColumns);
    this.rows.sort = this.sort;
    this.rows.paginator = this.paginator;
  }

  private updateColumns(): void {
    this.columns = ['select'];
    for (const column of Object.keys(this.displayedColumns[0])) {
      this.columns.push(column);
    }
  }

  private updateTable(): void {
    if (this.displayedColumns) {
      this.updateRows();
      this.updateColumns();
    }
  }

  public showUsers(): void {
    this.displayedColumns = UserInformation;
    this.updateTable();
    this.selection.clear();
  }

  item1() {
    alert('solved!!');
    // this.target.classList.add('class3');
  }

  dragStarted(event: CdkDragStart<string[]>, index: number ) {
    if (event) {
    this.previousIndex = index;
  }
  }

  dropListDropped(event: CdkDropList<string[]>, index: number) {
    if (event) {
      moveItemInArray(this.columns, this.previousIndex, index);
    }
  }


//HTML TABLE
<mat-table [dataSource]="rows" class="mat-elevation-z8" cdkDropListGroup matSort matSortActive="symbol" matSortDirection="asc">
    <ng-container *ngFor="let column of columns; let i = index" matColumnDef="{{column}}">
      <span *ngIf="i === 0">
        <mat-header-cell *matHeaderCellDef>
          <mat-checkbox (change)="$event ? masterToggle() : null"
                        [checked]="selection.hasValue() && isAllSelected()"
                        [indeterminate]="selection.hasValue() && !isAllSelected()"
                        [aria-label]="checkboxLabel()">
          </mat-checkbox>
        </mat-header-cell>
        <mat-cell *matCellDef="let row">
          <mat-checkbox (click)="$event.stopPropagation()"
                        (change)="$event ? selection.toggle(row) : null"
                        [checked]="selection.isSelected(row)"
                        [aria-label]="checkboxLabel(row)">
          </mat-checkbox>
        </mat-cell>
      </span>
      <span *ngIf="i !== 0">
        <mat-header-cell *matHeaderCellDef
          cdkDropList
          cdkDropListLockAxis="x"
          cdkDropListOrientation="horizontal"
          (cdkDropListDropped)="dropListDropped($event, i)"
          cdkDrag
          (cdkDragStarted)="dragStarted($event, i)"
          [cdkDragData]="{name: column, columIndex: i}"
          mat-sort-header>
          {{ column }}
        </mat-header-cell>
        <mat-cell *matCellDef="let row" > {{ row[column] }}  </mat-cell>
      </span>
    </ng-container>
    <mat-header-row *matHeaderRowDef="columns; sticky: true;"></mat-header-row>
    <mat-row *matRowDef="let row; columns: columns;" (click)="selection.toggle(row)" [routerLink]="['']"></mat-row>
  </mat-table>
  <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>

抱歉,这是很多代码,但是 table 中发生了很多事情。我真的只是希望得到正确的指示,让 "header" 中列出的 table headers 连接到 displayedColumns 以显示在 table header 而不是 UserInformation 数组中的值。非常感谢任何帮助。

无需为 headers 使用额外的数组,只需在 mat-header-cell 中添加一个管道即可将键转换为显示的值。 例如,参见此 Stackblitz