Как я могу иметь вложенные сортировки мат-таблицы? - PullRequest
3 голосов
/ 02 апреля 2020

Ciao,

Я играю с Angular 8, и мне нужна одна главная таблица с расширяемыми строками, и для каждой строки мне нужно просмотреть детали.

Моя настоящая проблема заключается в что сортировка работает только на родительском столе, а не на дочерних.

Это мой HTML код:

<table mat-table [dataSource]="dataSource" multiTemplateDataRows matSort #sorter1="MatSort">
    <ng-container matColumnDef="id">
        <th mat-header-cell *matHeaderCellDef> ID </th>
        <td mat-cell *matCellDef="let element"> {{ element.id }} </td>
    </ng-container>

    <ng-container matColumnDef="expandedDetail">
        <td mat-cell *matCellDef="let element" [attr.colspan]="2">
            <div>
                <table mat-table [dataSource]="dataSource2" matSort #innerSorts="MatSort">
                    <ng-container matColumnDef="id">
                        <th mat-header-cell *matHeaderCellDef> ID </th>
                        <td mat-cell *matCellDef="let element"> {{ element.id }} </td>
                    </ng-container>

                    <tr mat-header-row *matHeaderRowDef="['id']"></tr>
                    <tr mat-row *matRowDef="let element; columns: ['id'];"></tr>
                </table>
            </div>
        </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="['id']"></tr>
    <tr mat-row *matRowDef="let element; columns: ['id'];"
        class="example-element-row"
        [class.example-expanded-row]="expandedElement === element"
        (click)="clickRow(element)">
    </tr>
    <tr mat-row *matRowDef="let row; columns: ['expandedDetail']"></tr>
</table>

Это мой код TypeScript:

imports ...

@Component({
selector: 'my-nested-tables',
styleUrls: ['my-nested-tables.css'],
templateUrl: 'my-nested-tables.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)')),
    ]),
],
})
export class MyNestedTablesComponent {
    @Input() element: Array<Element>;
    @Input() element2: Array<Element>;

    dataSource1: MatTableDataSource<Element>(this.element);
    dataSource2: MatTableDataSource<Element>(this.element2);
    expandedElement: Element;

    @ViewChild("sorter1", {static:true}) sorter1: MatSort;
    @ViewChildren("innerTables") tables: QueryList<MatTable<Element>>
    @ViewChildren("innerSorts") innerSorts: QueryList<MatSort>;

    constructor(private cd: ChangeDetectorRef) { }

    ngOnInit() {
        this.dataSource.sort = sorter1;

    }

    ngOnChanges(change: SimpleChanges) {
        this.dataSource1.data = this.element;
        this.dataSource2.data = this.element2;
    }

    clickRow(element: Element) : void {
        this.expandedElement = this.expandedElement === element ? null : element;
        this.onLoadMyNestedElement.emit(this.expandedElement.id); // This is a event that update the element2 property (HTTP request).
        this.cd.detectChanges();
        this.tables.forEach((table, index) => (table.dataSource as MatTableDataSource<Element>).sort = this.innerSorts.toArray()[index]);
    }
}

export class Element {
    public id: number;
}

Вы можете мне помочь?

Грац ie Милле!

1 Ответ

1 голос
/ 14 апреля 2020

Таблицы материалов могут быть сложными и разочаровывающими для соединения, особенно с сортировкой и фильтрацией.

Что поможет упростить вещи, это разбить внутренние таблицы на отдельный компонент и добавить ссылка на родительскую таблицу.

Это также имеет преимущество, заключающееся в возможности отдельного тестирования. Попробуйте следующую настройку (я не могу убедиться, что это работает, но это будет хорошее начало)

main-table.component.ts

<inner-table [data]="element.data"></inner-table>

inner-table.component.ts

import { MatTableDataSource, MatSort } from '@angular/material';
import { Component, Input, ViewChild } from '@angular/core';

@Component({
  selector: "inner-table",
  template: `
    <table mat-table [dataSource]="dataSource" matSort>
      <ng-container matColumnDef="id">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
        <td mat-cell *matCellDef="let element">{{ element.id }}</td>
      </ng-container>

      <tr mat-header-row *matHeaderRowDef="['id']"></tr>
      <tr mat-row *matRowDef="let element; columns: ['id']"></tr>
    </table>
  `
})
export class InnerTableComponent {
  @Input()
  set data(newData: []) {
    this.dataSource.data = newData;
  }

  dataSource: MatTableDataSource<Element>;

  @ViewChild(MatSort, {static: false}) sort: MatSort;

  ngOnInit() {
    this.dataSource = new MatTableDataSource();
    this.dataSource.sort = this.sort;
  }
}

Я также создал собственную таблицу материалов angular под названием ngx-auto-table , чтобы помочь с таблицами данных , проверьте, это может вам помочь.

...