Tìm kiếm trang web

angular - Vấn đề biểu tượng Mở rộng Thu gọn MatTable khi phân trang và sắp xếp


Tôi có một bảng Angular Material sử dụng directive detailRow để chèn một dòng chi tiết/dòng kề bên cho một dòng trong bảng.

StackBlitz

Tôi muốn tạo cho nó vẻ ngoài như thể hàng đang được mở rộng hoặc thu gọn, vì vậy tôi đã thêm vài biểu tượng vào đó mà có thể chuyển đổi khi nhấp vào ô chứa chúng.

<mat-header-cell *matHeaderCellDef> Action </mat-header-cell>
      <mat-cell *matCellDef="let element"> 
         <button mat-icon-button color="primary"  (click)="element[i] = !element[i]">
            <mat-icon id="expand_more"  #expand_more *ngIf="!element[i] "  >expand_more</mat-icon>
            <mat-icon id="expand_less"  #expand_less *ngIf="element[i] ">expand_less</mat-icon>
          </button> 
      </mat-cell>

Tuy nhiên, nếu tôi để hàng mở rộng và phân trang hoặc sắp xếp, các biểu tượng sẽ không chuyển đổi vì không có cách nào để chúng được chuyển đổi.

Tôi đã thử kết nối vào sự kiện page hoặc sự kiện sortChange nhưng không có kết quả.

Tôi biết rằng có một cách mới để thực hiện mở rộng/thu gọn trong Angular Material v7 có lẽ hoạt động tốt với phân trang và sắp xếp nhưng sẽ mất một thời gian trước khi tôi nâng cấp, trong khi đó có ai có ý tưởng nào về cách giải quyết vấn đề này không.

Câu trả lời #1

Câu trả lời ngắn

Trong cdk-detail-row.directive.ts thêm cái này

  ngOnDestroy(): void {
    this.row[undefined] = false;
  }

Câu trả lời dài

Trước hết, bạn đang bắt sự kiện click ở 2 chỗ, một là ở mat-row và cái còn lại ở mat-cell (Nhấp vào biểu tượng sẽ kích hoạt cả hai sự kiện. Nhấp vào bất cứ nơi nào khác trên hàng chỉ kích hoạt onToggleChange). Và cũng cần nói rằng element[i]=!element[i] là một mẹo - (biến i chưa được định nghĩa). Vì vậy, nếu bạn nhấp vào bất cứ nơi nào khác trong hàng, biểu tượng mở rộng sẽ không thay đổi, đây là lý do tại sao tôi nhầm, vì tôi nghĩ nó không nên thay đổi. Ví dụ này sẽ chỉ loại bỏ việc click trên mat-cell để làm cho nó đơn giản.

Trong table-basic-example.html bạn nên loại bỏ đầu ra (click) khỏi nó và thêm đối số row vào phương thức onToggleChange($event, row). Và thay đổi *ng-if để lắng nghe element.close thay vào đó

<ng-container matColumnDef="expandCollapse">
  <mat-header-cell *matHeaderCellDef> Action </mat-header-cell>
  <mat-cell *matCellDef="let element"> 
     <button mat-icon-button color="primary">
        <mat-icon id="expand_more"  #expand_more *ngIf="!element.close"  >expand_more</mat-icon>
        <mat-icon id="expand_less"  #expand_less *ngIf="element.close">expand_less</mat-icon>
      </button> 
  </mat-cell>
</ng-container>

<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"
        class="element-row"
        [cdkDetailRow]="row" [cdkDetailRowTpl]="tpl"
        (toggleChange)="onToggleChange($event, row)">
</mat-row>

table-basic-example.ts

Thêm thuộc tính close vào phần tử giao diện

export interface Element {
    name: string;
    position: number;
    weight: number;
    symbol: string;
    close?: boolean;
}

Bây giờ chúng ta sẽ xử lý việc đóng và mở hàng trong phương thức onToggleChange.

onToggleChange(cdkDetailRow: CdkDetailRowDirective, row: Element): void {
    if (this.singleChildRowDetail && this.openedRow && this.openedRow.expended) {
        this.openedRow.toggle();
    }
    if (!row.close) {
        row.close = true;
    } else {
        row.close = false;
    }
    this.openedRow = cdkDetailRow.expended ? cdkDetailRow : undefined;
}

Cuối cùng, trong cdk-detail-row.directive.ts chúng ta sẽ muốn đóng hàng một khi directive bị hủy bởi phân trang hoặc chuyển đổi. Vì vậy chúng ta sẽ triển khai phương thức onDestroy

export class CdkDetailRowDirective implements OnDestroy{
     ...Details of implementation.....
}

Phương thức ngOnDestroy mới nên trông như thế này

ngOnDestroy(): void {
  this.row.close = false;
}

Bài viết liên quan