typescript 一个组件中的多个材料分页在 Angular 中不起作用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50428605/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:25:15  来源:igfitidea点击:

Multiple material pagination in one component doesn't work in Angular

angulartypescriptangular-materialangular-material2angular-datatables

提问by Sithys

I try to create a component which includes two dataTables each of it with another dataSource. My Tables aren't visible right after the component is loaded because of my *ngIfso that i couldn't use ngAfterViewInit()instead i'm using a solution a user pointed out on Github:

我尝试创建一个组件,其中包含两个数据表,每个数据表和另一个数据源。由于我的原因,在加载组件后我的表格不可见,*ngIf因此我无法使用ngAfterViewInit()我正在使用用户在 Github 上指出的解决方案:

  private paginator: MatPaginator;
  private reportingPaginator: MatPaginator;
  private sort: MatSort;
  private reportingSort: MatSort;

  @ViewChild(MatSort) set matSort(ms: MatSort) {
    this.sort = ms;
    this.reportingSort = ms;
    this.setDataSourceAttributes();
  }

  @ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
    this.paginator = mp;
    this.reportingPaginator = mp;
    this.setDataSourceAttributes();
  }

  setDataSourceAttributes() {

      this.dataSource.paginator = this.paginator;
      this.dataSource.sort = this.sort;

      this.reportingDataSource.paginator = this.reportingPaginator;
      this.reportingDataSource.sort = this.reportingSort;

}

But i still can't get it to work. My Pagination doesn't work, when both paginators are included into the @ViewChild(MatPaginator). If i only include one of the paginators

但我仍然无法让它工作。当两个分页器都包含在@ViewChild(MatPaginator). 如果我只包括其中一个分页器

@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
    this.reportingPaginator = mp;
    this.setDataSourceAttributes();
}

or

或者

@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
    this.paginator = mp;
    this.setDataSourceAttributes();
}

the one i included works fine!So what do i need to do to get both paginators work?

我包括的一个工作正常!那么我需要做什么才能让两个分页器工作?

回答by Manish Salian

For mutiple MatPaginator and MatSort components present in single page you need yo use

对于单页中存在的多个 MatPaginator 和 MatSort 组件,您需要使用

@ViewChildren(MatPaginator) paginator = new QueryList<MatPaginator>();
@ViewChildren(MatSort) sort = new QueryList<MatSort>();

in your code which will return you list of MatSort and MatPaginator defined in the order in which it is present int your page. Below is the complete implemetation

在您的代码中,它将返回您按页面中出现的顺序定义的 MatSort 和 MatPaginator 列表。下面是完整的实现

import { Component, OnInit, ViewChild, ViewChildren, AfterViewInit, QueryList } from '@angular/core';
import { MatTableDataSource, MatSort, MatPaginator } from '@angular/material';

export interface AssignmentElement {
  assignmentId: number;
  action: string;
  userName: string;
  roleName: string;
  enabled: string;
  createdOn: string;
  createdBy: string;
  modifiedOn: string;
  modifiedBy: string;
  status: string;
}

export interface RoleElement {
  roleId: number;
  action: string;
  roleName: string;
  roleDescription: string;
  createdOn: string;
  createdBy: string;
  modifiedOn: string;
  modifiedBy: string;
  status: string;
}

export const ASSIGNMENT_ELEMENT_DATA: AssignmentElement[] = [
  { assignmentId: 1, action: 'Grant', userName: 'Dummy', roleName: 'admin', enabled: 'Y', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { assignmentId: 2, action: 'Grant', userName: 'Dummy', roleName: 'admin', enabled: 'Y', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { assignmentId: 3, action: 'Grant', userName: 'ADummy', roleName: 'admin', enabled: 'Y', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { assignmentId: 4, action: 'Grant', userName: 'Dummy', roleName: 'admin', enabled: 'Y', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { assignmentId: 8, action: 'Grant', userName: 'BDummy', roleName: 'admin', enabled: 'Y', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { assignmentId: 1, action: 'Grant', userName: 'Dummy', roleName: 'admin', enabled: 'Y', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { assignmentId: 12, action: 'Grant', userName: 'ZDummy', roleName: 'admin', enabled: 'Y', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { assignmentId: 12, action: 'Grant', userName: 'Dummy', roleName: 'admin', enabled: 'Y', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { assignmentId: 19, action: 'Grant', userName: 'Dummy', roleName: 'admin', enabled: 'Y', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { assignmentId: 111, action: 'Grant', userName: 'PDummy', roleName: 'admin', enabled: 'Y', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { assignmentId: 122, action: 'Grant', userName: 'Dummy', roleName: 'admin', enabled: 'Y', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { assignmentId: 133, action: 'Grant', userName: 'QDummy', roleName: 'admin', enabled: 'Y', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' }

];

export const ROLE_ELEMENT_DATA: RoleElement[] = [
  { roleId: 1, action: 'Create', roleName: 'admin', roleDescription: 'This is test role', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { roleId: 3, action: 'Create', roleName: 'cadmin', roleDescription: 'This is test role', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { roleId: 1, action: 'Create', roleName: 'admin', roleDescription: 'This is test role', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { roleId: 5, action: 'Create', roleName: 'vadmin', roleDescription: 'This is test role', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { roleId: 4, action: 'Create', roleName: 'zadmin', roleDescription: 'This is test role', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' },
  { roleId: 1, action: 'Create', roleName: 'admin', roleDescription: 'This is test role', createdOn: '21-Feb-2018', createdBy: 'Dummy', modifiedOn: '', modifiedBy: '', status: 'PENDING' }
];

@Component({
  selector: 'app-myqueue',
  templateUrl: './myqueue.component.html',
  styleUrls: ['./myqueue.component.css']
})
export class MyqueueComponent implements OnInit, AfterViewInit {

  dataSource1: MatTableDataSource<AssignmentElement>;
  dataSource2: MatTableDataSource<RoleElement>;
  @ViewChildren(MatPaginator) paginator = new QueryList<MatPaginator>();
  @ViewChildren(MatSort) sort = new QueryList<MatSort>();

  assignmentColumn: string[] = [
    'select', 'assignmentId', 'action', 'userName', 'roleName', 'enabled', 'createdOn', 'createdBy', 'modifiedOn', 'modifiedBy', 'status'
  ];
  roleColumn: string[] = [
    'select', 'roleId', 'action', 'roleName', 'roleDescription', 'createdOn', 'createdBy', 'modifiedOn', 'modifiedBy', 'status'
  ];

  constructor() {
    this.dataSource1 = new MatTableDataSource<AssignmentElement>(ASSIGNMENT_ELEMENT_DATA);
    this.dataSource2 = new MatTableDataSource<RoleElement>(ROLE_ELEMENT_DATA);
  }

  ngOnInit() {
  }

  ngAfterViewInit() {
    this.dataSource1.paginator = this.paginator.toArray()[0];
    this.dataSource1.sort = this.sort.toArray()[0];
    this.dataSource2.paginator = this.paginator.toArray()[1];
    this.dataSource2.sort = this.sort.toArray()[1];
  }

}

回答by Rob

You can retrieve them by #id also:

您也可以通过 #id 检索它们:

In your HTML:

在您的 HTML 中:

<mat-paginator #categoryPaginator [pageSizeOptions]="[15]" hidePageSize="true" showFirstLastButtons="false"></mat-paginator>

In your component TS:

在您的组件 TS 中:

@ViewChild('categoryPaginator', { read: MatPaginator }) categoryPaginator: MatPaginator;

EDIT

编辑

After seeing gh0st's comment I did some digging and it seems the "read" option is supposed to be a boolean ViewChild angular documentationso I did an experiment and { read: true } does not work - but {read: false} does - but given false is the default removing it altogether still works - so it seems this is the most succinct way to do this is:

在看到 gh0st 的评论后,我做了一些挖掘,似乎“读取”选项应该是一个布尔ViewChild 角度文档,所以我做了一个实验,{ read: true } 不起作用 - 但 {read: false} 可以 - 但给出false 是默认设置,完全删除它仍然有效 - 所以看起来这是最简洁的方法是:

@ViewChild('categoryPaginator') categoryPaginator: MatPaginator;

I have tested this with 3 tables/paginators in the one view component and they appear to still work as expected.

我已经在一个视图组件中使用 3 个表/分页器对此进行了测试,它们似乎仍然按预期工作。

I can only assume that { read: MatPaginator } is actually being interpreted as { read: false }

我只能假设 { read: MatPaginator } 实际上被解释为 { read: false }

The Angular documentation does actually give a rough example of this:

Angular 文档确实给出了一个粗略的例子:

A template reference variable as a string (e.g. query <my-component #cmp></my-component> with @ViewChild('cmp'))

EDIT-2

编辑-2

I encountered a scenario where I have two material autocompletes in one component and need to access the MatAutoComplete trigger for one of them - it seems in this instance the { read: MatAutocompleteTrigger } is essential otherwise it just returns an ElementRef:

我遇到了一个场景,我在一个组件中有两个材质自动完成,并且需要访问其中一个的 MatAutoComplete 触发器 - 在这种情况下,{ read: MatAutocompleteTrigger } 似乎是必不可少的,否则它只会返回一个 ElementRef:

@ViewChild('localityAutoComplete', { read: MatAutocompleteTrigger }) trigger: MatAutocompleteTrigger;