一个组件中有多个数据表[Angular Material Tables]排序,过滤和分页

时间:2019-11-24 12:57:14

标签: angular sorting datatables pagination components

我想知道是否有人解决过这个问题!

我目前正在开发一个AdministrationComponent(类似于CRUD操作的单例),旨在通过HTTP请求(封装在服务中)将操作发送到后端来管理4个不同表上的数据,然后将结果通过WebSockets发送到客户端(为将来有多个客户端同时在此组件上做准备)。

  • 我正在通过HTTP请求检索数据到后端,在每个表中显示它都没问题。

  • 我正在实例化“材料对话框”,该对话框封装了每个表的每个CRUD操作。这些经过验证和完成后,会将相应的HTTPRequest及其操作及其数据发送到后端。 (每个表都有自己的服务)

  • 然后,我有一个单独的服务,该服务实现WebSockets,并且这是一个更新表上显示的数据的服务(因为此AdministrationComponent将由多个客户端使用)。

我必须根据多个表中存在的数据进行验证(也许不称为验证(?))。 例如:假设我们有表A,B和C。A中的一项可以与C中的项相关,但是只有在A和B都具有共同属性的情况下才可以访问。 由于此类操作存在于多个表中,因此我打算保留这种单例组件体系结构,但是请证明我错了。

现在,问题: 由于在表格上显示数据工作正常,所以我的问题是每个表格的排序,过滤和分页

代码上似乎没有错误,但是它仅适用于第一个表,不适用于其他表,因为我无法弄清楚如何正确引用matSort和matPaginator。 最初,我正在为matSort和matPaginator做ViewChild,例如:

@Component({
  selector: 'app-administration',
  templateUrl: './administration.component.html',
  styleUrls: ['./administration.component.scss']
})
export class AdministrationComponent implements OnInit {
    users: any = [];  
    userTable_displayedColumns: string[] = ['name', 'organization', 'updatedAt', 'userActionsColumn'];
    userTable_dataSource: MatTableDataSource<any>;
    @ViewChild(MatPaginator, { static: true }) userTable_paginator: MatPaginator;
    @ViewChild(MatSort, { static: true }) userTable_sort: MatSort;

    userTable_applyFilter(filterValue: string): void {
        this.userTable_dataSource.filter = filterValue.trim().toLowerCase();
        if (this.userTable_dataSource.paginator) {
          this.userTable_dataSource.paginator.firstPage();
        }
      }

    constructor (/* service Injection here */) {

        this.userTable_dataSource = new MatTableDataSource;
        // initialization of table with Promised HTTP request
        // initialization of websockets channel which updates the data according to the backend

        // this is done for the 4 different tables

    }

    ngOnInit(): void {
        this.userTable_dataSource.paginator = this.userTable_paginator;
        this.userTable_dataSource.sort = this.userTable_sort;
        // this is done for the 4 different tables
    }

    // and the rest of the code here is filtering on the different tables, 
    //as well as launching Material Dialogs which are working fine
}

和模板(每个表位于其自己的选项卡中):

    <!-- Users -->
    <div class="tab-pane active" id="link1">

      <div class="row">
        <div class="col-md">
          <button class="btn btn-enging btn-fill btn-wd mat-raised-button" mat-raised-button="" type="submit"
            (click)="openDialogCreateUser()">
            <span class="mat-button-wrapper">
              <i class="material-icons">person_add</i> Adicionar Utilizador
            </span>
            <div class="mat-button-ripple mat-ripple" matripple=""></div>
            <div class="mat-button-focus-overlay"></div>
          </button>
        </div>
        <div class="col-md-6">
          <mat-form-field class="example-full-width">
            <input matInput placeholder="Encontrar..." (keyup)="userTable_applyFilter($event.target.value)"
              value="">
          </mat-form-field>
        </div>
      </div>
      <div class="mat-elevation-z8">
        <table mat-table [dataSource]="userTable_dataSource" matSort>
          <tr mat-header-row *matHeaderRowDef="userTable_displayedColumns"></tr>
          <ng-container matColumnDef="userType">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Tipo de User </th>
            <td mat-cell *matCellDef="let row"> {{row.userType}} </td>
          </ng-container>
          <ng-container matColumnDef="username">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Username </th>
            <td mat-cell *matCellDef="let row"> {{row.username}} </td>
          </ng-container>
          <ng-container matColumnDef="name">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Nome </th>
            <td mat-cell *matCellDef="let row"> {{row.name}} </td>
          </ng-container>
          <ng-container matColumnDef="email">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Email </th>
            <td mat-cell *matCellDef="let row"> {{row.email}} </td>
          </ng-container>
          <ng-container matColumnDef="organization">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Organização </th>
            <td mat-cell *matCellDef="let row"> {{getOrganizationNameByID(row.organization)}} </td>
          </ng-container>
          <ng-container matColumnDef="updatedAt">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Último login </th>
            <td mat-cell *matCellDef="let row"> {{row.updatedAt | date:'HH:mm, dd/MM/y' }} </td>
          </ng-container>
          <ng-container matColumnDef="userActionsColumn">
            <th mat-header-cell *matHeaderCellDef mat-sort-header style="white-space: nowrap;"> Acções </th>
            <td mat-cell *matCellDef="let row">
              <div class="row">
                <span class="mat-button-wrapper" (click)="openDialogViewUser(row)" style="cursor: pointer">
                  <i class="material-icons" style="color:#163b65">remove_red_eye</i>
                </span>
                <span class="mat-button-wrapper" (click)="openDialogEditUser(row)" style="cursor: pointer">
                  <i class="material-icons" style="color:rgba(22, 59, 101, 1)">edit</i>
                </span>
                <span class="mat-button-wrapper" (click)="openDialogRemoveUser(row)" style="cursor: pointer">
                  <i class="material-icons" style="color:rgba(22, 59, 101, 1)">clear</i>
                </span>
              </div>
            </td>
          </ng-container>
          <tr mat-row *matRowDef="let row; columns: userTable_displayedColumns;"></tr>
        </table>
        <mat-paginator [pageSizeOptions]="[10, 25, 100]"></mat-paginator>
      </div>

    </div>
    <!-- Organizations, and so on ... -->

但是,然后,我弄清楚了如何正确使用ViewChild(我想),并尝试了:(引用:https://stackoverflow.com/a/49015542/8919846

@ViewChild('userTablePaginator', { static: true }) userTable_paginator: MatPaginator;
@ViewChild('userTableSort', { static: true }) userTable_sort: MatSort;

模板:

<table mat-table [dataSource]="userTable_dataSource" #userTableSort="matSort" matSort>
<mat-paginator #userTablePaginator="matSort" [pageSizeOptions]="[10, 25, 100]"></mat-paginator>

但是它不起作用。

有人知道如何使它起作用吗? :)

1 个答案:

答案 0 :(得分:0)

我想我看到你的问题了。让我们从ViewChild开始。

这将为您带来第一个分页器,并将其分配给userTable_paginator。如果您还有其他分页器,则将无法像第一个那样访问它们并绑定适当的表分页器:

this.userTable_dataSource.paginator = this.userTable_paginator;

那么,你该怎么办。对于每个分页器,请在模板参考中使用不同的ViewChild

<mat-paginator #userPaginator [pageSizeOptions]="[10, 25, 100]"></mat-paginator>

和TS

@ViewChild('userPaginator', { static: true }) userTable_paginator: MatPaginator;

您还可以使用ViewChildren将它们全部放入QueryList中并从那里进行操作(尤其是如果您有一些动态添加/删除操作。ViewChildren将在您更新时更新)添加/删除MatPaginator