【问题标题】:Multiple mat-table with MatSort within the same component在同一个组件中使用 MatSort 的多个 mat-table
【发布时间】:2017-11-13 18:43:29
【问题描述】:

我在同一个组件中有 2 个材料 2 个表并进行排序。我找不到将 MatSort 指令分配给它自己的表的方法。我只能在第一张桌子上使用 MatSort,而第二张桌子不知道上面有 MatSort。有谁知道如何配置两个表在同一个组件中排序?

我尝试用不同的名称定义 ViewChild,但没有成功。

@ViewChild('hBSort') hBSort: MatSort;
@ViewChild('sBSort') sBSort: MatSort;


this.hBSource = new HBDataSource(this.hBDatabase, this.hBPaginator, 
this.hBSort);
this.sBSource = new SBDataSource(this.sBDatabase, this.sBPaginator, 
this.sBSort);

Table 1
const displayDataChanges = [
   this.hBPaginator.page,
   this.hBSort.sortChange,
   this._filterChange
];

Table 2
const displayDataChanges = [
   this.sBPaginator.page,
   this.sBSort.sortChange,
   this._filterChange
];

Table 1
<mat-table #hBtable [dataSource]="hBSource" matSort style="min-width: 
740px;">
    <ng-container matColumnDef="domain">
        <mat-header-cell *matHeaderCellDef mat-sort-header> {{'list.domain' | translate}} </mat-header-cell>
        <mat-cell *matCellDef="let row"> {{row.domain}} </mat-cell>
    </ng-container>
    <ng-container matColumnDef="general">
        <mat-header-cell *matHeaderCellDef mat-sort-header> {{'list.general' | translate}} </mat-header-cell>
        <mat-cell *matCellDef="let row"> {{row.general.gNum}} ({{row.general.gPct | number: '1.1-2'}}%) </mat-cell>
    </ng-container>
    <mat-header-row *matHeaderRowDef="hBColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: hBColumns;"></mat-row>
 </mat-table>


Table 2
<mat-table #sBSort [dataSource]="sBSource" matSort style="min-width: 1200px;">
      <ng-container matColumnDef="domain">
        <mat-header-cell *matHeaderCellDef mat-sort-header> {{'list.domain' | translate}} </mat-header-cell>
        <mat-cell *matCellDef="let row"> {{row.domain}} </mat-cell>
      </ng-container>
      <ng-container matColumnDef="general">
        <mat-header-cell *matHeaderCellDef mat-sort-header> {{'list.general' | translate}} </mat-header-cell>
        <mat-cell *matCellDef="let row"> {{row.general.gNum}} ({{row.general.gPct | number: '1.1-2'}}%) </mat-cell>
      </ng-container>
      <mat-header-row *matHeaderRowDef="sBColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns: sBColumns;"></mat-row>
</mat-table>

【问题讨论】:

    标签: angular angular-material2


    【解决方案1】:

    解决此问题的方法是,在 DOM 中定义 ViewChild 引用后,您需要确保在其后添加 ="matSort"。

    步骤:

    1. 在您的组件中设置 MatSort 实例并在您的 DataSource 依赖项中定义它们,如下所示:

      @ViewChild('hBSort') hBSort: MatSort;
      @ViewChild('sBSort') sBSort: MatSort;
      
      this.hBSource = new HBDataSource(this.hBDatabase, this.hBPaginator, 
      this.hBSort);
      this.sBSource = new SBDataSource(this.sBDatabase, this.sBPaginator, 
      this.sBSort);
      
    2. 在 DOM 中定义 ViewChild 引用并将它们设置为等于 matSort(注意:matSort 属性在 mat-table 标签上):

      Table 1
      <mat-table #hBSort="matSort" [dataSource]="hBSource" matSort 
        style="min-width: 740px;">
                  ***Table Rows and pagination***
      </mat-table>
      
      Table 2
      <mat-table #sBSort="matSort" [dataSource]="sBSource" matSort 
        style="min-width: 1200px;">
                  ***Table Rows and pagination***
      </mat-table>   
      

    【讨论】:

    • 另外,如果孩子在启动时被隐藏,您可能需要其他技巧,请参阅github.com/angular/material2/issues/10205
    • 如果使用 *ngIf 隐藏表,则可以,因为 DOM 中不存在 ViewChild 引用。如果使用 [hidden] 隐藏表格,那么它应该可以正常工作。
    • 我不知道为什么,我尝试了一个看起来一样的不同答案,这对我有用。谢谢。 PS> 我正在使用角度 8
    【解决方案2】:

    在 Angular 7、9 和 10 中,您需要 both matSort 和参考 #sorter1="matSort":

    <table mat-table [dataSource]="ds1" matSort #sorter1="matSort">
    </table>
    <table mat-table [dataSource]="ds2" matSort #sorter2="matSort">
    </table>
    

    然后

    @ViewChild('sorter1') sorter1: MatSort;
    @ViewChild('sorter2') sorter2: MatSort;
    
    
    ngOnInit() {
    this.ds1.sort = this.sorter1;
    this.ds2.sort = this.sorter2;
    }
    

    【讨论】:

    • 这对我来说也非常适合 Angular 9。谢谢。
    • 在 Angular 10 也可以工作。
    • 按预期工作:)
    • 解释清楚,适用于 angular 12。
    【解决方案3】:

    我建议为表格创建一个通用组件,它可以在应用程序的多个位置使用。由于组件将创建它的单独实例,因此 mat table 不会与那里的功能发生冲突。

    在这种情况下,您不需要为 2 个表重复代码。下面是您可以实现的 Table 通用组件。

    Home.component.ts

    export class HomeComponent implements OnInit {
      public data1: any[];
      public data2: any[];
      constructor() {
      }
      ngOnInit() {
       this.data1 = [
        {domain: 'Hello1', gNum: 1, gPct: 'table-data1'},
        {domain: 'Hello2', gNum: 2, gPct: 'table-data2'},
        {domain: 'Hello3', gNum: 3, gPct: 'table-data3'},
        {domain: 'Hello4', gNum: 4, gPct: 'table-data4'},
        {domain: 'Hello5', gNum: 5, gPct: 'table-data5'},
        {domain: 'Hello6', gNum: 6, gPct: 'table-data6'},
        {domain: 'Hello7', gNum: 7, gPct: 'table-data7'},
       ];
       this.data2 = [
        {domain: 'Hello1', gNum: 1, gPct: 'table-data1'},
        {domain: 'Hello2', gNum: 2, gPct: 'table-data2'},
        {domain: 'Hello3', gNum: 3, gPct: 'table-data3'},
        {domain: 'Hello4', gNum: 4, gPct: 'table-data4'},
        {domain: 'Hello5', gNum: 5, gPct: 'table-data5'},
        {domain: 'Hello6', gNum: 6, gPct: 'table-data6'},
        {domain: 'Hello7', gNum: 7, gPct: 'table-data7'},
       ]
      }
    }
    

    Home.component.html

     <app-table-component [data]='data1'></app-table-component>
     <app-table-component [data]='data2'></app-table-component>
    

    Table.component.ts

    @Component({
      selector: 'app-table-component',
      templateUrl: 'table.component.html',
      styleUrls: ['table.component.scss'],
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    
    export class TableComponent implements OnInit, OnChanges {
      @ViewChild(MatPaginator) paginator: MatPaginator;
      @ViewChild(MatSort) sort: MatSort;
      @Input() data: any[];
      public displayedColumns = ['domain', 'gNum', 'gPct'];
      public dataSource: MatTableDataSource<any>;
    
      constructor() {
      }
    
      public ngOnInit() {
        setTimeout(() => {
            this.dataSource = new MatTableDataSource(this.data);
            this.dataSource.paginator = this.paginator;
            this.dataSource.sort = this.sort;
       });
      }
    
      public ngOnChanges(changes: SimpleChanges) {
        this.dataSource = new MatTableDataSource(changes.data.currentValue);
      }
    
    }
    

    Table.component.html

       <mat-table #table [dataSource]="dataSource" matSort  matSortDisableClear matSortDirection="asc">
      <ng-container matColumnDef="domain">
        <mat-header-cell *matHeaderCellDef mat-sort-header>Domain </mat-header-cell>
        <mat-cell *matCellDef="let row"> {{row.domain}} </mat-cell>
      </ng-container>
    
     <ng-container matColumnDef="gNum">
        <mat-header-cell *matHeaderCellDef mat-sort-header>G Number </mat-header-cell>
        <mat-cell *matCellDef="let row"> {{row.gNum}} </mat-cell>
      </ng-container>
    
      <ng-container matColumnDef="gPct">
        <mat-header-cell *matHeaderCellDef mat-sort-header>Global Pct </mat-header-cell>
        <mat-cell *matCellDef="let row"> {{row.gPct}} </mat-cell>
      </ng-container>
    
      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row  *matRowDef="let row; columns: displayedColumns;">
      </mat-row>
    </mat-table>
    
    <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
    

    【讨论】:

    • 我同意使用组件总是更好。在我的情况下,每个表的数据列都非常不同,因此出于这些目的,我没有制作每个表可以共享的组件。虽然,我可以制作一个具有动态列和数据类的组件。感谢您提供另一种观点!
    【解决方案4】:

    这是一个 Angular 6 工作解决方案:

    import { MatSort, MatTableDataSource } from '@angular/material';
    

    ...

    @ViewChild('sortCol1') sortCol1: MatSort;
    @ViewChild('sortCol2') sortCol2: MatSort;
    

    ...

    数据源一:

    this.dataSource1 = new MatTableDataSource(this.dataSource1);
    this.dataSource1.sort = this.sortCol1;
    

    数据源2:

    this.dataSource2 = new MatTableDataSource(this.dataSource2);
    this.dataSource2.sort = this.sortCol2;
    

    ...

    表 1(视图):

    <table mat-table #sortCol1="matSort" [dataSource]="dataSource1" matSort matSortActive="ID" matSortDirection="asc">
    ...
    </table>
    

    表 2(视图):

    <table mat-table #sortCol2="matSort" [dataSource]="dataSource2" matSort matSortActive="ID" matSortDirection="asc">
    ...
    </table>
    

    【讨论】:

      【解决方案5】:

      编辑:

      我相信你需要:

      @ViewChild(MatSort) sort: MatSort;
      

      在你的上方:

      @ViewChild('hBSort') hBSort: MatSort;
      @ViewChild('sBSort') sBSort: MatSort;
      

      然后:

      ngAfterViewInit() {
          this.hBSource.sort = this.sort;
          this.sBSource.sort = this.sort;
        }
      

      假设你的 HBDataSource 和 SBDataSource 都导出 MatTableDataSource();

      我参考了这些来源:

      https://material.angular.io/components/sort/overview https://github.com/angular/material2/blob/master/src/demo-app/table/table-demo.ts

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-07
      • 1970-01-01
      • 1970-01-01
      • 2020-01-25
      • 2019-07-08
      • 1970-01-01
      • 2020-02-01
      • 2018-05-21
      相关资源
      最近更新 更多