ค้นหาเว็บไซต์

typescript - การแบ่งหน้าหลายวัสดุในคอมโพเนนต์เดียวไม่ทำงานใน Angular


ฉันพยายามสร้างคอมโพเนนต์ที่รวมตารางข้อมูลสองตารางโดยแต่ละตารางมีแหล่งข้อมูลของมันเอง ตารางของฉันไม่ปรากฏทันทีหลังจากที่คอมโพเนนต์ถูกโหลดเนื่องจาก *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;

}

แต่ฉันยังไม่สามารถทำให้มันทำงานได้ การแบ่งหน้า (Pagination) ของฉันไม่ทำงาน เมื่อทั้งตัวแบ่งหน้า (paginators) ถูกใส่เข้าไปใน @ViewChild(MatPaginator) หากฉันใส่เพียงตัวแบ่งหน้าเดียว

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

หรือ

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

อันที่ฉันใส่ไปใช้งานได้ดี! งั้นฉันต้องทำอะไรบ้างเพื่อให้ตัวแบ่งหน้าทั้งสองทำงาน?

คำตอบ #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];
  }

}

คำตอบ #2

คุณสามารถดึงมันออกมาตาม #id ได้เช่นกัน:

ใน HTML ของคุณ:

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

ใน TS ของคอมโพเนนต์ของคุณ:

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

แก้ไข

หลังจากเห็นความคิดเห็นของ gh0st ฉันได้ลองค้นหาดูและดูเหมือนว่าตัวเลือก "read" ควรจะเป็น boolean ในเอกสาร Angular ของ ViewChild ดังนั้นฉันจึงทดลองและพบว่า { 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'))

แก้ไข-2

ฉันพบสถานการณ์ที่ฉันมี autocompletes ของวัสดุสองอันในคอมโพเนนต์เดียวและจำเป็นต้องเข้าถึงทริกเกอร์ MatAutoComplete สำหรับหนึ่งในนั้น - ดูเหมือนว่าในกรณีนี้ { read: MatAutocompleteTrigger } จำเป็นมิฉะนั้นมันจะส่งกลับเพียง ElementRef:

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

บทความที่เกี่ยวข้อง