【问题标题】:Angular material sorting table not working角料分拣台不工作
【发布时间】:2021-12-19 12:00:28
【问题描述】:

我正在使用 Angular Material,并在模板的 for 循环中生成表格。我想为这些生成的表添加排序和分页,但我尝试的方法不起作用。 我有一个组列表,每个组都有它的项目,这是一个表格,我希望能够按 price, quantity, sales 排序。

groups: any[] = [
    {
      name: 'Group 1',
      items: [
        { name: 'Product 1', price: 20, quantity: 33, sales: 11 },
        { name: 'Product 2', price: 10, quantity: 43, sales: 11 },
        { name: 'Product 3', price: 23, quantity: 63, sales: 11 },
      ],
    },
    {
      name: 'Group 2',
      items: [
        { name: 'Product 2', price: 40, quantity: 33, sales: 11 },
        { name: 'Product 4', price: 10, quantity: 143, sales: 211 },
        { name: 'Product 61', price: 63, quantity: 63, sales: 151 },
      ],
    },
    {
      name: 'Group 20',
      items: [
        { name: 'Product 22', price: 40, quantity: 33, sales: 11 },
        { name: 'Product 14', price: 10, quantity: 143, sales: 211 },
      ],
    },
  ];

在 HTML 上我有这些:

<div *ngFor="let group of groups">
  <p>{{ group.name }}</p>
  <div class="mat-elevation-z8">
    <table [dataSource]="group.items" mat-table matSort>
      <ng-container matColumnDef="name">
        <th *matHeaderCellDef mat-header-cell>Name</th>
        <td *matCellDef="let element" mat-cell>{{ element.name }}</td>
      </ng-container>
      <ng-container matColumnDef="price">
        <th *matHeaderCellDef mat-sort-header mat-header-cell>Price</th>
        <td *matCellDef="let element" mat-cell>{{ element.price }}</td>
      </ng-container>
      <ng-container matColumnDef="quantity">
        <th *matHeaderCellDef mat-sort-header mat-header-cell>Quantity</th>
        <td *matCellDef="let element" mat-cell>{{ element.quantity }}</td>
      </ng-container>
      <ng-container matColumnDef="sales">
        <th *matHeaderCellDef mat-sort-header mat-header-cell>Sales</th>
        <td *matCellDef="let element" mat-cell>{{ element.sales }}</td>
      </ng-container>
      <tr *matHeaderRowDef="displayedColumns" mat-header-row></tr>
      <tr *matRowDef="let row; columns: displayedColumns" mat-row></tr>
    </table>
  </div>
</div>

有人可以帮我吗?

签入stackblitz

【问题讨论】:

    标签: javascript angular typescript sorting angular-material


    【解决方案1】:

    下面的解决方案将每个排序后的 Material 表的 HTML 脚本移动到它自己的组件中。

    由于您的 HTML 有一个包含多个 mat-table 组件的循环,我建议您尝试以下方法:

    创建一个组件app-my-sorted-table,其中包含您的材料表的HTML模板,并通过输入data传递数据,如图所示:

    <div *ngFor="let group of groups">
      <p>{{ group.name }}</p>
      <div class="mat-elevation-z8">
        <app-my-sorted-table [data]="group.items"></app-my-sorted-table>
      </div>
    </div>
    

    您的组件 HTML 将如下所示:

    <table [dataSource]="dataSource" mat-table matSort>
      <ng-container matColumnDef="name">
        <th *matHeaderCellDef mat-header-cell>Name</th>
        <td *matCellDef="let element" mat-cell>{{ element.name }}</td>
      </ng-container>
      <ng-container matColumnDef="price">
        <th *matHeaderCellDef mat-sort-header mat-header-cell>Price</th>
        <td *matCellDef="let element" mat-cell>{{ element.price }}</td>
      </ng-container>
      <ng-container matColumnDef="quantity">
        <th *matHeaderCellDef mat-sort-header mat-header-cell>Quantity</th>
        <td *matCellDef="let element" mat-cell>{{ element.quantity }}</td>
      </ng-container>
      <ng-container matColumnDef="sales">
        <th *matHeaderCellDef mat-sort-header mat-header-cell>Sales</th>
        <td *matCellDef="let element" mat-cell>{{ element.sales }}</td>
      </ng-container>
      <tr *matHeaderRowDef="displayedColumns" mat-header-row></tr>
      <tr *matRowDef="let row; columns: displayedColumns" mat-row></tr>
    </table>
    

    您的组件源包括数据输入将是这样的:

    @Component({
      selector: 'app-my-sorted-table',
      templateUrl: './my-sorted-table.component.html',
      styleUrls: ['./my-sorted-table.component.css'],
    })
    export class MySortedTableComponent implements AfterViewInit {
      @ViewChild(MatSort) sort: MatSort;
    
      dataSource = new MatTableDataSource([]);
    
      _data: any[] = [];
      @Input()
      get data(): any[] {
        return this._data;
      }
      set data(value: any[]) {
        this.dataSource = new MatTableDataSource(value);
        this.dataSource.sort = this.sort;
      }
    
      displayedColumns: string[] = ['name', 'price', 'quantity', 'sales'];
    
      ngAfterViewInit() {
        console.log('sorting .. ');
        this.dataSource.sort = this.sort;
      }
    }
    

    以上将MatSort的实例和数据源封装到循环内重复使用的共享组件中。

    要在材料表的代码中包含排序,您需要包含以下导入:

    导入物料分类模块:

    import { MatSortModule } from '@angular/material/sort';
    

    另外,每个使用Material表和列排序的组件中都需要导入以下类型:

    import { MatSort } from '@angular/material/sort';
    

    一旦应用了上述更改,循环内每个表中的表列将具有基本的升序和降序排序。

    以下是上述解决方案的链接:

    https://stackblitz.com/edit/playground-angular-11-material-eoqltm?file=src/app/my-sorted-table/my-sorted-table.component.ts

    【讨论】:

    • type 'MatSort' is not assignable to type '(compareFn?: ((a: any, b: any) =&gt; number) | undefined) =&gt; any[]'.   Type 'MatSort' provides no match for the signature '(compareFn?: ((a: any, b: any) =&gt; number) | undefined): any[]'. 我收到了这个错误
    • 我去看看。
    • 您找到任何解决方案了吗?
    • 我将更新我的答案以包括声明数据源。那你可以试试看。
    • 但是使用您的解决方案,我必须定义 sort1 ,sort2 etc,而在 ng 循环中,我不知道我是否会有 0 个表或 100 个表。这是行不通的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    • 1970-01-01
    • 2017-08-27
    • 2020-08-07
    • 2022-11-17
    • 2015-03-08
    相关资源
    最近更新 更多