3

I have a page with a Material table. The table has a custom data source since pagination is server side. It also has a check box column. The rows in the table are expandable.

Problem: The expandable rows work fine until I go to some other page and reroute to the above page again. When I reroute back to the page many rows are in expanded state automatically.

I found one question with a similar issue : Similar problem However I don't have tabs so the solution mentioned can't be applied to my problem and fundamentally I am not sure why the solution works.

Code snippet which adds the expandable row to the table:

<ng-container matColumnDef="expandedDetail">
      <td mat-cell *matCellDef="let element" [attr.colspan]="displayedColumns.length">
        <div [@detailExpand]="element === expandedElement ? 'expanded' : 'collapsed'">
         <div>Expandable row details go here</div>
        </div>
      </td>
    </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns; sticky:true"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns"
      (click)="toggle(row); expandedElement = expandedElement == row ? null : row"
      [class.element-expanded-row]="expandedElement == element" class="clickable-row element-row">
    </mat-row>
    <mat-row *matRowDef="let row; columns: ['expandedDetail'];"
      [@detailExpand]="row === expandedElement ? 'expanded' : 'collapsed'">
    </mat-row>
  </mat-table>

In the TS file I have a variable which I reset to null on ngOnInit:

expandedElement: any;

Also, One more behavior that I observed when I come back to the page was that I have to click the row twice to close it which means the condition to collapse and open the row (element === expandedElement) is satisfied just that the row is visible when I come back to the page.

Does any one has any clue what may be the problem?

Edit :

The expandable table example on angular materials page doesn't have to use [@detailExpand] for the expand detail mat-row however I have to use otherwise I see a empty row in between 2 rows of data. Why so? Does it have to do anything with this problem?

 <mat-row *matRowDef="let row; columns: ['expandedDetail'];"
      [@detailExpand]="row === expandedElement ? 'expanded' : 'collapsed'">
    </mat-row>
humbleCoder
  • 667
  • 14
  • 27

2 Answers2

1

This issue describes the same problem. Basically Sorting breaks animation. In my case as well if I turn off sorting the animation works fine.

Final solution : Use ngClass with CSS animations. Got the solution from the following answer : https://stackoverflow.com/a/65198370/1711670.

humbleCoder
  • 667
  • 14
  • 27
0

By default, the tab contents are eagerly loaded.
Eagerly loaded tabs will initalize the child components but not inject them into the DOM until the tab is activated.

If the tab contains several complex child components or the tab's contents rely on DOM calculations during initialization, it is advised to lazy load the tab's content.
(The expandable table is based on DOM calculations)

Tab contents can be lazy loaded by declaring the body in a ng-template with the matTabContent attribute.

Search for lazy loading in https://material.angular.io/components/tabs/overview


EDIT
I don't know what you are trying to do but the simple expandable table in angular is like this:

<table mat-table
       [dataSource]="dataSource" multiTemplateDataRows
       class="mat-elevation-z8">
  <ng-container matColumnDef="{{column}}" *ngFor="let column of columnsToDisplay">
    <th mat-header-cell *matHeaderCellDef> {{column}} </th>
    <td mat-cell *matCellDef="let element"> {{element[column]}} </td>
  </ng-container>

  <!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
  <ng-container matColumnDef="expandedDetail">
    <td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplay.length">
      <div class="example-element-detail"
           [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
        <div class="example-element-description">
         here the data you want to display
        </div>
      </div>
    </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="columnsToDisplay; sticky:'true'"></tr>
  <tr mat-row *matRowDef="let row; columns: columnsToDisplay;"
      class="example-element-row"
      [class.example-expanded-row]="expandedElement == element"
      (click)="toggle(row); expandedElement = expandedElement === row ? null : row">
  </tr>
  <tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
</table>
<mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>

DETAIL EXPAND

This is used for trigger the animation

@Component({
  selector: "table-expandable-rows-example",
  styleUrls: ["table-expandable-rows-example.css"],
  templateUrl: "table-expandable-rows-example.html",
  animations: [
    trigger("detailExpand", [
      state("collapsed", style({ height: "0px", minHeight: "0" })),
      state("expanded", style({ height: "*" })),
      transition(
        "expanded <=> collapsed",
        animate("225ms cubic-bezier(0.4, 0.0, 0.2, 1)")
      )
    ])
  ]
})
Antonio Esposito
  • 301
  • 2
  • 13
  • Thanks however I still don't get what ng-template and lazy loading has to do with the expandable row. Also I dont have tabs. I just have a table in my view. The table documentation doesnt have anything related to lazy loading. – humbleCoder Dec 30 '20 at 04:58
  • Yes I have done the same and its working fine until I go to some other page and come back to the page with the table. When I come back all table rows are expanded. You can see the problem here except that I am not using tabs : https://stackblitz.com/edit/angular-wat7fa-wzk7sh?file=app/table-expandable-rows-example.html – humbleCoder Dec 31 '20 at 06:00
  • In that link the problem is tabs and lazy loading, if you could share the component.ts maybe we would found the error. – Antonio Esposito Dec 31 '20 at 23:34