Расширяемые строки таблицы в angular 4 с материалом angular

Как бы вы сделали строки расширяемыми в таблицах угловых материалов? Одно из требований - использовать таблицу угловых материалов. Я также предпочел бы использовать материал аккордеона для информации, представленной здесь.

Я хочу нажать на строку и показать различную информацию для каждого столбца. Я ищу что-то вроде ниже. Если щелкнуть строку 1, строки 2 и 3 появятся с разными данными.

enter image description here

Ответ 1

Как упомянул здесь Эндрю Сегин, это уже выполнимо из коробки: использование предиката when.

Посмотрите этот пример: https://stackblitz.com/edit/angular-material-expandable-table-rows (спасибо Лакстону)

demo

Внутри тега mat-table вы должны использовать компонент mat-row с директивой matRipple. При нажатии на строку элемент строки будет назначен на expandedElement переменной:

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

Но теперь мы должны добавить нашу расширенную строку, которая по умолчанию скрыта и будет показана, если пользователь нажмет на строку выше:

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

Важно здесь уже упомянутый when предикат. Это вызывает функцию isExpansionDetailRow которая определена в самом компоненте, и проверяет, имеет ли detailRow свойство detailRow:

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

Начиная с RC0 первым параметром является индекс:

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

Если вы хотите иметь расширенное представление для каждой строки, вы должны добавить "ExpansionDetailRow", определяемый свойством detailRow для каждой строки, например:

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

Если вы rows переменную row в вывод консоли, это будет выглядеть так:

console output

РЕДАКТИРОВАТЬ: ПОЛНЫЙ ПРИМЕР С ИСПОЛЬЗОВАНИЕМ DIRECTIVE

Расширяемые строки таблицы Mat (сортировка, разбиение на страницы и фильтрация)

Ответ 2

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

Вкратце: используйте таблицу материалов и добавьте метод click к строкам:

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

Добавьте компонент для расширенной области. row_detail.html содержит html, который находится в расширенной области.

@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;
}

В вашем компоненте, где находится таблица, вам нужен метод для расширения строки. Сначала добавьте это в ваш компонент...

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

... а затем добавьте метод:

/**
   * 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";
    }
}

Ответ 3

Вот как вы можете сделать это с Angular Material. Этот пример включает в себя разбиение на страницы и один пример с mat-sort-header в столбце name. Мне пришлось переопределить mat paginator и выполнить пользовательскую сортировку, чтобы убедиться, что расширяемая строка все еще оставалась родительской при сортировке. Этот пример также позволяет открывать несколько строк одновременно и закрывать все строки

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

Ответ 4

Когда CDK был единственным способом получить что-то близкое к Material Table, использование md-row в обычной таблице было жизнеспособной альтернативой, но поскольку таблицы @angular/material 2.0.0-beta.12 ditched CDK и теперь имеют свои собственные таблицы данных, может соответствовать вашим потребностям. См. Документацию ниже:

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