Implementing Expandable Rows in Angular Material Tables: A Complete Solution Based on the when Predicate

Dec 06, 2025 · Programming · 9 views · 7.8

Keywords: Angular Material | Expandable Table | when Predicate | mat-table | detailRow Property

Abstract: This article provides an in-depth technical guide for implementing expandable row functionality in Angular 4+ using Angular Material tables. It thoroughly analyzes the when predicate mechanism of mat-table components, the implementation logic of mat-row expansion, and special data structure handling. The article includes complete code examples and implementation steps, with particular emphasis on the critical role of the detailRow property and the data association mechanism between expanded rows and main rows.

Technical Background and Requirements Analysis

In modern web application development, expandable functionality in data tables has become an essential feature for enhancing user experience. Angular Material, as a mature UI component library in the Angular ecosystem, provides powerful data presentation capabilities through its table component mat-table. However, the official documentation does not directly offer built-in expandable row implementation, requiring developers to combine existing features.

Core Implementation Principles

The key to implementing expandable rows lies in utilizing the when predicate functionality of mat-table. This feature allows dynamic rendering of different row templates based on specific conditions. Specifically, two types of rows need to be defined: main rows (containing primary data) and expanded rows (containing detailed data). These row types are distinguished through an identifier property (typically named detailRow).

Data Structure Design

The data source requires special processing to add a corresponding expanded row object for each main data element. Example code:

connect(): Observable<Element[]> {
    const rows = [];
    data.forEach(element => rows.push(element, { detailRow: true, element }));
    return Observable.of(rows);
}

This structure creates an alternating array: main row data objects followed immediately by their corresponding expanded row objects. The expanded row object contains two key properties: detailRow: true as a type identifier, and element referencing the original data for access within the expanded row.

Template Implementation

In the HTML template, two types of mat-row need to be defined:

<mat-row *matRowDef="let row; columns: displayedColumns;"
        matRipple 
        class="element-row" 
        [class.expanded]="expandedElement == row"
        (click)="expandedElement = row">
</mat-row>

Main rows toggle the expandedElement variable through click events, controlling which row is in the expanded state.

The definition of expanded rows is more critical:

<mat-row *matRowDef="let row; columns: ['expandedDetail']; when: isExpansionDetailRow"
        [@detailExpand]="row.element == expandedElement ? 'expanded' : 'collapsed'"
        style="overflow: hidden"> 
</mat-row>

Here, when: isExpansionDetailRow specifies that this row template is used only for rows satisfying the isExpansionDetailRow function condition.

Predicate Function Implementation

The predicate function identifies expanded rows:

isExpansionDetailRow = (i: number, row: any) => row.hasOwnProperty('detailRow');

Starting from Angular Material RC0, this function receives two parameters: row index and row data. The function checks whether the row data contains the detailRow property to determine whether to use the expanded row template.

Styling and Animation

Expand/collapse effects are achieved through CSS class binding and Angular animations:

[class.expanded]="expandedElement == row"

This adds specific style classes to the currently expanded row, while the [@detailExpand] animation binding controls the display animation of expanded rows.

Advanced Feature Integration

This solution integrates seamlessly with other Angular Material table features:

Performance Optimization Considerations

For large datasets, consider:

  1. Using trackBy functions to optimize rendering performance
  2. Integrating virtual scrolling
  3. Implementing lazy loading for expanded row content

Practical Application Recommendations

In actual projects, it is recommended to encapsulate expandable row functionality as reusable directives or components. This not only improves code reusability but also simplifies maintenance. Additionally, ensure expanded row content is responsively designed to adapt to different screen sizes.

Common Issue Resolution

Potential issues during implementation include:

Conclusion

By properly utilizing the when predicate functionality of Angular Material tables and designing flexible data structures, fully functional and high-performance expandable row tables can be implemented. This solution not only meets basic expand/collapse requirements but also provides a solid foundation for more complex data presentation scenarios.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.