一个组件中的多个 material 分页在 Angular 中不起作用
Multiple material pagination in one component doesn't work in Angular
我尝试创建一个组件,其中包含两个数据表,每个数据表都有另一个数据源。由于我的 *ngIf
,我的表在组件加载后不可见,因此我无法使用 ngAfterViewInit()
,而是使用用户 pointed out on Github:[=19 的解决方案=]
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();
}
我包含的那个工作正常!那么我需要做什么才能让两个分页器工作?
对于单个页面中存在的多个 MatPaginator 和 MatSort 组件,您需要使用
@ViewChildren(MatPaginator) paginator = new QueryList<MatPaginator>();
@ViewChildren(MatSort) sort = new QueryList<MatSort>();
在您的代码中,return 您将列出 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];
}
}
您也可以通过#id 检索它们:
在你的HTML中:
<mat-paginator #categoryPaginator [pageSizeOptions]="[15]" hidePageSize="true" showFirstLastButtons="false"></mat-paginator>
在你的组件中 TS:
@ViewChild('categoryPaginator', { read: MatPaginator }) categoryPaginator: MatPaginator;
编辑
看到 gh0st 的评论后我做了一些挖掘,似乎 "read" 选项应该是一个布尔值 ViewChild angular documentation 所以我做了一个实验并且 { read: true } 不起作用 - 但是{read: false} 确实如此——但假设 false 是默认的,将其完全删除仍然有效——所以这似乎是最简洁的方法:
@ViewChild('categoryPaginator') categoryPaginator: MatPaginator;
我已经在一个视图组件中用 3 tables/paginators 测试了这个,它们似乎仍然按预期工作。
我只能假设 { 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
我遇到了这样一种情况,我在一个组件中有两个 material 自动完成,并且需要为其中一个访问 MatAutoComplete 触发器 - 在这种情况下似乎 { read: MatAutocompleteTrigger } 是必不可少的,否则它只是returns 一个元素引用:
@ViewChild('localityAutoComplete', { read: MatAutocompleteTrigger }) trigger: MatAutocompleteTrigger;
我尝试创建一个组件,其中包含两个数据表,每个数据表都有另一个数据源。由于我的 *ngIf
,我的表在组件加载后不可见,因此我无法使用 ngAfterViewInit()
,而是使用用户 pointed out on Github:[=19 的解决方案=]
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();
}
我包含的那个工作正常!那么我需要做什么才能让两个分页器工作?
对于单个页面中存在的多个 MatPaginator 和 MatSort 组件,您需要使用
@ViewChildren(MatPaginator) paginator = new QueryList<MatPaginator>();
@ViewChildren(MatSort) sort = new QueryList<MatSort>();
在您的代码中,return 您将列出 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];
}
}
您也可以通过#id 检索它们:
在你的HTML中:
<mat-paginator #categoryPaginator [pageSizeOptions]="[15]" hidePageSize="true" showFirstLastButtons="false"></mat-paginator>
在你的组件中 TS:
@ViewChild('categoryPaginator', { read: MatPaginator }) categoryPaginator: MatPaginator;
编辑
看到 gh0st 的评论后我做了一些挖掘,似乎 "read" 选项应该是一个布尔值 ViewChild angular documentation 所以我做了一个实验并且 { read: true } 不起作用 - 但是{read: false} 确实如此——但假设 false 是默认的,将其完全删除仍然有效——所以这似乎是最简洁的方法:
@ViewChild('categoryPaginator') categoryPaginator: MatPaginator;
我已经在一个视图组件中用 3 tables/paginators 测试了这个,它们似乎仍然按预期工作。
我只能假设 { 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
我遇到了这样一种情况,我在一个组件中有两个 material 自动完成,并且需要为其中一个访问 MatAutoComplete 触发器 - 在这种情况下似乎 { read: MatAutocompleteTrigger } 是必不可少的,否则它只是returns 一个元素引用:
@ViewChild('localityAutoComplete', { read: MatAutocompleteTrigger }) trigger: MatAutocompleteTrigger;