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

Posted

技术标签:

【中文标题】一个组件中的多个材料分页在 Angular 中不起作用【英文标题】:Multiple material pagination in one component doesn't work in Angular 【发布时间】:2018-10-29 21:58:13 【问题描述】:

我尝试创建一个组件,其中包含两个数据表,每个数据表和另一个数据源。由于我的*ngIf,在组件加载后我的表格不可见,因此我无法使用ngAfterViewInit(),而是使用用户pointed out on 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;


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

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

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

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

【问题讨论】:

这种情况下需要使用@ViewChildren吗? 如何用 ViewChildren 解决这个问题? :( 我想不通...我想只是以正确的方式实例化它,以便那个展位在 viewChild 内工作。如果我只放一个进去,它就可以工作。 如果页面上有多个MatPaginator,那么@ViewChildren(MatPaginator) 应该给你QueryList<MatPaginator>,根据docs。您对该列表的处理取决于您最终要执行的操作。 【参考方案1】:

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

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

在您的代码中,它将返回 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];
  


【讨论】:

this.paginator.toArray is not a function 它给了我 this.paginator.toArray 不是函数 toArray() 仍然存在于 QueryList 中。除非您的变量(分页器)未初始化为 QueryList 实例,否则您将收到该错误。 angular.io/api/core/QueryList#toarray 对于那些想要简短的人,@ViewChildren(MatPaginator) paginator = new QueryList(); this.dataSource1.paginator = this.paginator.toArray()[0]; this.dataSource2.paginator = this.paginator.toArray()[1]; @ManishSalian - 你的回答很有帮助。我终于让它与少量添加一起工作。与大多数示例或示例不同,我的两个表的数据源都是动态的。在 AfterViewInit 期间数据源不可用。这导致第二个分页无法正常工作。为了纠正这种行为,我用空数组初始化了两个数据源并且它起作用了。空数组示例:dataSource: MatTableDataSource = new MatTableDataSource(); dataSourceDetails: MatTableDataSource = new MatTableDataSource(); @ManishSalian 上述解决方案有问题,即``` this.dataSource1.paginator = this.paginator.toArray()[0]; this.dataSource1.sort = this.sort.toArray()[0];``` 只会修复特定行的分页,有没有办法可以循环遍历数据源并分配 this.paginator.toArray() [index] 到数据源的分页器?这就是我想要达到的目标***.com/questions/66813576/…【参考方案2】:

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

在您的 HTML 中:

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

在您的组件 TS 中:

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

编辑

看到 gh0st 的评论后,我进行了一些挖掘,似乎“读取”选项应该是布尔值 ViewChild angular documentation,所以我做了一个实验, read: true 不起作用 - 但 read: false 可以- 但是给定 false 是默认删除它仍然有效 - 所以看起来这是最简洁的方法是:

@ViewChild('categoryPaginator') categoryPaginator: MatPaginator;

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

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

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

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

EDIT-2

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

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

【讨论】:

这应该被标记为答案。你能找到支持这一点的文档吗? @gh0st 我已经更新了答案以包含对 Angular 文档的引用,并且还修改了解决方案,因为它比我最初想象的还要简单。

以上是关于一个组件中的多个材料分页在 Angular 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

ListView中多个上下文中特定上下文的分页在django中不起作用?

Wordpress 分页在搜索结果中不起作用

Angular 材料 2:如何区分一个组件中的 2 个或多个可排序表?

如何将从服务接收到的 json 数据传递到 Angular 4 的角材料组件中的数组

使用分页在primefaces数据网格上更改页面时更新组件

android:背景在材料设计按钮组件中不起作用