MatTable Expand Collapse Icon issue on pagination and sort

只愿长相守 提交于 2019-11-30 09:14:53

问题


I've a angular material table which uses detailRow directive to insert a detail/sibling adjacent row to a table row.

StackBlitz

I wanted to give it an appearance of as if the row is being expanded or collapsed, so I added couple of icons to it which are toggled on the click of cell containing them.

<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>

However if the I leave the row expanded and paginate or do a sort the icons do not toggle because there's no way for them to be toggled.

I've tried hooking into the page event or the sortChange event but came up empty.

I'm aware that there's new way to do expand/collapse in angular material v7 which probably works well with pagination and sort but its gonna be a while before I upgrade, in the mean time does anyone have any ideas on how to solve this.


回答1:


Short Answer

In cdk-detail-row.directive.ts add this

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

Long Answer

Firstly, You are capturing click in 2 places once in mat-row and the other in mat-cell(Clicking on the icon triggers both events. Clicking anywhere else on the row only triggers onToggleChange). And also this element[i] = !element[i] is a hack - (variable i is undefined). So if you click anywhere else in the row the expand icon does not change this is why I got confused as I thought it is not suppose to change. The example will just take out the click on mat-cell to make it simple.

In table-basic-example.html you should remove the (click) output from it and add the row argument to the method onToggleChange($event, row). And change the *ng-if to listen to element.close instead

<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

Add the close property to interface element

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

Now we will handle the close and open of the row in the method 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;
}

Lastly, In cdk-detail-row.directive.ts we will want to close the row once the directive is destroyed by pagination or toggling away. So we will implement the onDestroy method

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

The new ngOnDestroy method should look like this

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


来源:https://stackoverflow.com/questions/53775715/mattable-expand-collapse-icon-issue-on-pagination-and-sort

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!