typescript - Flera materialpagineringar i en komponent fungerar inte i Angular
Jag försöker skapa en komponent som inkluderar två dataTabeller, var och en med en annan dataKälla. Mina tabeller är inte synliga direkt efter att komponenten laddats på grund av mitt *ngIf, så att jag inte kunde använda ngAfterViewInit(). Istället använder jag en lösning som en användare påpekade på 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;
}
Men jag kan fortfarande inte få det att fungera. Min paginering fungerar inte när båda paginatorerna inkluderas i @ViewChild(MatPaginator). Om jag bara inkluderar en av paginatorerna
@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
this.reportingPaginator = mp;
this.setDataSourceAttributes();
}
eller
@ViewChild(MatPaginator) set matPaginator(mp: MatPaginator) {
this.paginator = mp;
this.setDataSourceAttributes();
}
den jag inkluderade fungerar bra! Så vad behöver jag göra för att få båda paginerarna att fungera?
Svar #1
För flera MatPaginator- och MatSort-komponenter på en enda sida behöver du använda
@ViewChildren(MatPaginator) paginator = new QueryList<MatPaginator>();
@ViewChildren(MatSort) sort = new QueryList<MatSort>();
i din kod som kommer att returnera en lista med MatSort och MatPaginator definierade i den ordning de finns på din sida. Nedan är den fullständiga implementeringen
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];
}
}
Svar #2
Du kan även hämta dem via #id:
I din HTML:
<mat-paginator #categoryPaginator [pageSizeOptions]="[15]" hidePageSize="true" showFirstLastButtons="false"></mat-paginator>
I din komponent TS:
@ViewChild('categoryPaginator', { read: MatPaginator }) categoryPaginator: MatPaginator;
REDIGERA
Efter att ha sett gh0st:s kommentar gjorde jag lite efterforskningar och det verkar som att alternativet "read" ska vara en boolean enligt ViewChild Angular-dokumentationen, så jag gjorde ett experiment och { read: true } fungerar inte - men { read: false } fungerar - men eftersom false är standardvärdet fungerar det fortfarande att ta bort det helt - så det verkar som att det mest kortfattade sättet att göra detta är:
@ViewChild('categoryPaginator') categoryPaginator: MatPaginator;
Jag har testat detta med 3 tabeller/paginators i samma vykomponent och de verkar fortfarande fungera som förväntat.
Jag kan bara anta att { read: MatPaginator } faktiskt tolkas som { read: false }
Angular-dokumentationen ger faktiskt ett ungefärligt exempel på detta:
A template reference variable as a string (e.g. query <my-component #cmp></my-component> with @ViewChild('cmp'))
REDIGERA-2
Jag stötte på ett scenario där jag har två material-autocomplete i en komponent och behöver komma åt MatAutoComplete-triggern för en av dem - det verkar i detta fall att { read: MatAutocompleteTrigger } är nödvändigt annars returnerar det bara en ElementRef:
@ViewChild('localityAutoComplete', { read: MatAutocompleteTrigger }) trigger: MatAutocompleteTrigger;
