Expandable table rows in angular 4 with angular material

前端 未结 4 1299
别跟我提以往
别跟我提以往 2020-11-28 02:54

How would you make rows expandable in angular material tables? One requirement is that I need to be using the angular material table. I would also prefer to use the material

相关标签:
4条回答
  • 2020-11-28 03:15

    It is not possible out of the box, but you can solve it with a little custom code. Take a look at this discussion and this solution (not from me, but the basis for this answer).

    In short: Use the material table and add a click-method to the rows:

    <md-row *mdRowDef="let row; columns: displayedColumns; let index=index" (click)="expandRow(index, row)" #myRow></md-row>
    

    Add a component for the expanded area. The row_detail.html contains the html which is in the expanded area.

    @Component({
      selector: 'app-inline-message',
      templateUrl: 'row_detail.html',
      styles: [`
        :host {
          display: block;
          padding: 24px;
          background: rgba(0,0,0,0.03);
        }
      `]
    })
    export class InlineMessageComponent {
      @Input() content1: string;
      @Input() content2: string;
    }
    

    In your component where the table lives you need the method to expand the row. First, add this to your component...

    expandedRow: number;
    @ViewChildren('myRow', { read: ViewContainerRef }) containers;
    

    ... and then add the method:

    /**
       * Shows the detail view of the row
       * @param {number} index
       */
    expandRow(index: number, row: DataFromRowFormat) {
    
        if (this.expandedRow != null) {
          // clear old message
          this.containers.toArray()[this.expandedRow].clear();
        }
    
        if (this.expandedRow === index) {
          this.expandedRow = null;
        } else {
          const container = this.containers.toArray()[index];
          const factory: ComponentFactory<InlineMessageComponent> = this.resolver.resolveComponentFactory(InlineMessageComponent);
          const messageComponent = container.createComponent(factory);
    
          messageComponent.instance.content1= "some text";
          messageComponent.instance.content2 = "some more text";
        }
    }
    
    0 讨论(0)
  • 2020-11-28 03:19

    When CDK was the only way to get something close to a Material Table, using md-row's in a regular table was a viable alternative, but since @angular/material 2.0.0-beta.12 ditched CDK tables and now have their own Data Tables that might fit your needs. See documentation below:

    https://material.angular.io/components/table/overview

    0 讨论(0)
  • 2020-11-28 03:21

    As mentioned here by Andrew Seguin this is already feasible out of the box: using the when predicate.

    See this example: https://stackblitz.com/edit/angular-material-expandable-table-rows (thx to Lakston)

    Inside of the mat-table tag you have to use the mat-row component with a matRipple directive. When you click on a row the row element will be assigned to the expandedElement variable:

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

    But now we have to add our expanded row, that is hidden by default and will be shown if the user clicks on the row above:

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

    Important is here the already mentioned when predicate. This calls a isExpansionDetailRow function that is defined in the component itself and checks if the row has a detailRow property:

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

    Since RC0 the first param is the index:

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

    If you want to have an expanded view for every row, you have to add an "ExpansionDetailRow" identified by the detailRow property for every row like this:

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

    If you would log the rows variable to the console output, it will look like this:

    EDIT: COMPLETE EXAMPLE USING DIRECTIVE

    Mat Table expandable rows (sorting, pagination and filtering)

    0 讨论(0)
  • 2020-11-28 03:28

    Here is how you can do it with Angular Material. This example includes pagination and one example with mat-sort-header on the 'name' column. I had to override mat paginator and do a custom sort to make sure the expandable row was still by its parent when it was sorted. This example also allows you to open multiple rows at a time and to close all rows

    https://stackblitz.com/edit/angular-material2-issue-zs6rfz

    0 讨论(0)
提交回复
热议问题