Angular Material 表不显示数据,给出 _columnCssClassName is not iterable 错误

问题描述 投票:0回答:2

我有一个 Angular Material 应用程序,我试图向所有客户展示我从 API 调用中获得的信息...我的应用程序已编译,但在浏览器控制台中我不断收到此错误:

错误错误:未捕获(承诺中):类型错误: columnDef._columnCssClassName 不可迭代(无法读取属性 未定义)类型错误:columnDef._columnCssClassName 不可迭代 (无法读取未定义的属性)

我做错了什么?我怀疑这与我将数据输入表列的方式有关

我创建了一个名为 Customers 的接口,其结构如下:

export interface Customers {
  _links: {
    first: {
      href: string;
    };
    last: {
      href: string;
    };
    next: {
      href: string;
    }
    self: {
      href: string;
    };
  };
  _embedded: {
    customers: [
      {
        id: string;
        internal_id: string;
        name: string;
        name2: string;
        address: string;
        address_post_nr: string;
        phone: string;
        email: string;
        gdpr: string,
        mailing: string,
        tags: string;
      }
    ]
  };
  page: number;
  page_count: number;
  page_size: number;
  total_items: number;
}

然后我创建了一个组件,我想在包含以下列的表格中向我的客户显示:ID、姓名、地址、电子邮件、邮寄、gdpr、标签

这是component.ts文件代码:

export class CustomersComponent implements OnInit, OnDestroy{

  displayedColumns: string [] = ['Id', 'name', 'address', 'email', 'mailing', 'gdpr', 'tags'];
  public dataSource: MatTableDataSource<Customers["_embedded"]>;

  private customerSubscription: Subscription;

  @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
  @ViewChild(MatSort, { static: true }) sort: MatSort;

  private dataArray: any;
  constructor(
    private customersServcice: CustomersService,
  )
  { }

  ngOnInit() {
    this.getAllCustomers();
  }

  getAllCustomers() {
    this.customerSubscription = this.customersServcice.getAllCustomersList().subscribe(
      (res) => {
        console.log('res: ', res);
        this.dataArray = res;
        this.dataSource = new MatTableDataSource<Customers["_embedded"]>(this.dataArray);
        console.log('this.dataSource: ', this.dataSource);
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
      });
  }

  ngOnDestroy() {
    if(this.customerSubscription) {
      this.customerSubscription.unsubscribe();
    }
  }
}

这是组件 html 表代码:

  <table mat-table [dataSource]="dataSource" class="crm-table mat-elevation-z0">
    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef> Id </th>
      <td mat-cell *matCellDef="let element" class="left-text"> {{element.id}} </td>
    </ng-container>
    <ng-container matColumnDef="name">
      <th mat-header-cell *matHeaderCellDef> Name </th>
      <td mat-cell *matCellDef="let element" class="left-text"> {{element.name}} </td>
    </ng-container>
    <ng-container matColumnDef="address">
      <th mat-header-cell *matHeaderCellDef> Address </th>
      <td mat-cell *matCellDef="let element" class="left-text"> {{element.address}} </td>
    </ng-container>
    <ng-container matColumnDef="email">
      <th mat-header-cell *matHeaderCellDef> Email </th>
      <td mat-cell *matCellDef="let element" class="left-text"> {{element.email}} </td>
    </ng-container>
    <ng-container matColumnDef="mailing">
      <th mat-header-cell *matHeaderCellDef> Mailing </th>
      <td mat-cell *matCellDef="let element" class="left-text"> {{element.mailing}} </td>
    </ng-container>
    <ng-container matColumnDef="gdpr">
      <th mat-header-cell *matHeaderCellDef> GDPR </th>
      <td mat-cell *matCellDef="let element" class="left-text"> {{element.gdpr}} </td>
    </ng-container>
    <ng-container matColumnDef="tags">
      <th mat-header-cell *matHeaderCellDef> Tags </th>
      <td mat-cell *matCellDef="let element" class="left-text"> {{element.tags}} </td>
    </ng-container>
    <ng-container matColumnDef="">
      <th mat-header-cell *matHeaderCellDef> </th>
      <td mat-cell class="left-text"> + </td>
    </ng-container>
    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let element; columns: displayedColumns;"></tr>
  </table>
javascript angular typescript angular-material
2个回答
1
投票

怀疑问题出在

MatTableDataSource
的类型上。

public dataSource: MatTableDataSource<Customers["_embedded"]>

从所附的

<mat-table>
元素中,认为类型应该是:
Customers["_embedded"]["customers"][0]

  1. 更改
    MatTableDataSource
    的类型。
public dataSource: MatTableDataSource<Customers["_embedded"]["customers"][0]>;
  1. 同时更改
    MatTableDataSource
    Subscription
    的类型。确保
    dataArray
    Customers["_embedded"]["customers"][0]
    类型的数组。
this.dataSource = new MatTableDataSource<Customers["_embedded"]["customers"][0]>(this.dataArray);
  1. 此外,
    Id
    中的
    displayedColumns
    应为小写。
displayedColumns: string[] = ['id', 'name', 'address', 'email', 'mailing', 'gdpr', 'tags'];

或者我建议创建一个

CustomerItem
界面。

export interface CustomerItem {
  id: string;
  internal_id: string;
  name: string;
  name2: string;
  address: string;
  address_post_nr: string;
  phone: string;
  email: string;
  gdpr: string,
  mailing: string,
  tags: string;
}

export interface Customers {
  _links: {
    first: {
      href: string;
    };
    last: {
      href: string;
    };
    next: {
      href: string;
    }
    self: {
      href: string;
    };
  };
  _embedded: {
    customers: CustomerItem[]
  };
  page: number;
  page_count: number;
  page_size: number;
  total_items: number;
}

并将

dataSource
类型更改为:

public dataSource: MatTableDataSource<CustomerItem>;

0
投票

问题的根源似乎在于

 <ng-container matColumnDef="">
      <th mat-header-cell *matHeaderCellDef> </th>
      <td mat-cell class="left-text"> + </td>
 </ng-container>

这基本上意味着您没有提供任何类型的

matColumnDef
。 Angular Material 派生自它相应的 CSS 类。

为了完整起见:这同样适用于

    <tr *matNoDataRow matColumnDef="noData" class="mat-mdc-row">

这也需要

matColumnDef

© www.soinside.com 2019 - 2024. All rights reserved.