CDK Angular Table with dynamic checkboxes not finding correct column names

南楼画角 提交于 2019-12-24 06:14:24

问题


I have a dynamic CDK Angular Material mat-table that I have fixed a mat-checkbox to. It is populating data, but it is not allowing me to set the correct column headers. Everything that gets displayed is from the key:value pairs from the UserInformation array. However, I need to set a second array to display the correct header names as I will not have control of the key names coming from the API and will need to set them in the TypeScript. Not all information coming from the API will be displayed in the table. I will have multiple tables as well and need to make this completely reusable to where on the content being displayed will change in the TypeScript, everything else will be injected.

Right now I'm down to just getting the displayedColumn names to appear correctly in the 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>

Sorry this is a lot of code, but there is a lot happening in this table. I'm really just hoping to get pointed in the right direction to get the table headers listed from "header" that is connected to displayedColumns to display in the table header instead of the value from the UserInformation array. Any help is greatly appreciated.


回答1:


Instead of using an additional array for headers, simply add a pipe in mat-header-cell that transforms the key to a displayed value. See this Stackblitz for example.



来源:https://stackoverflow.com/questions/57812228/cdk-angular-table-with-dynamic-checkboxes-not-finding-correct-column-names

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!