Сортировка по умолчанию в Angular Material с вложенными объектами

Я использую матовую таблицу с сортировкой, где я хочу установить сортировку по умолчанию для определенного столбца.

Это работает для простых атрибутов, но не для вложенных.

Вот мой стол

<table mat-table [dataSource]="dataSource" multiTemplateDataRows 
       matSort matSortActive="break" matSortDirection="asc"
       class="mat-elevation-z4 w-100">

Моя вложенная сортировка

this.dataSource.sort = this.sort;
   this.dataSource.sortingDataAccessor = (item, property) => {
   switch(property) {
      case 'break': return item.break.start;
      default: return item[property];
   }
};

Также эта вложенная сортировка в порядке, когда вы вручную нажимаете на заголовок для сортировки, она делает то, что я ожидаю, но по умолчанию она не сортируется, а только показывает стрелку сортировки.

Вот как это выглядит при загрузке страницы:

Вот соответствующий stackblitz.


person Norbert Bartko    schedule 10.10.2019    source источник
comment
это может помочь или вы можете добавить демонстрацию stackblitz, если проблема все еще существует   -  person jitender    schedule 10.10.2019
comment
К сожалению, это решение не работает для вложенных объектов.   -  person Norbert Bartko    schedule 10.10.2019


Ответы (3)


Первоначальная сортировка не работала должным образом, когда я исследовал ее в мае.

В моем случае нужно было написать свою функцию setSortHeader, которая выполняется после получения данных.

setSortHeader() {
  this.sort.active = 'break';
  this.sort.direction = 'desc';
  this.sort.sortChange.emit({ active: this.sort.active, direction: this.sort.direction });

  const sortHeader = this.sort.sortables.get('break');
  if (sortHeader) sortHeader['_setAnimationTransitionState']({ toState: 'active' });
}

Я не уверен, что этот код все еще необходим, но в моем случае это сработало.

person vadjs    schedule 10.10.2019

<ng-container matColumnDef="firstName">
    <th mat-header-cell class="mat-header-sticky" id="firstName" *matHeaderCellDef mat-sort-header tabindex="0"
      [attr.aria-label]="'First Name Tool Tip'" [matTooltip]="tooltipConfiguration['firstName']"
      [matTooltipPosition]="'above'" [matTooltipClass]="'matTooltip-panel'">
      First Name
    </th>
    <td mat-cell *matCellDef="let contact" class="align-center">
      <span class="display-block overflow-ellipsis">
        {{ contact.firstName }}
      </span>
    </td>
</ng-container>

Просто используйте те же matColumnDef="firstName" и {{ contact.firstName }}, обратите внимание, что свойство .firstName соответствует matColumnDef ID. Это согласно угловым документам.

person Destro    schedule 18.05.2021

Пожалуйста, попробуйте следующее.


Если вы хотите изменить направление по умолчанию, измените его при вызове метода ngOnInit на this.sortItem.

// app.component.ts

import { Component, ViewChild } from '@angular/core';

import { Sort, MatSort, MatPaginator } from '@angular/material';

import { interval } from 'rxjs';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  public displayedColumns: string[] = ['name', 'break',];

  public sortedData: any;

  constructor( ) { }

  ngOnInit() {
    setTimeout(() => {         
      this.sortItem({ active: 'break', direction: 'asc' });
    }, 1000);
  }
  compare(a: number | string, b: number | string, isAsc: boolean) {
    return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
  }

  sortItem(sort: Sort) {
    const data = DATA_SOURCE.slice();
    if (!sort.active || sort.direction === '') {
      this.sortedData = data;
      return;
    }

    this.sortedData = data.sort((a, b) => {
      const isAsc = sort.direction === 'asc';
      switch (sort.active) {
        case 'break': return this.compare(a.breakTime.start, b.breakTime.start, isAsc);        
        default: return 0;
      }
    });
  }
}

const DATA_SOURCE = [
  {
    name: 'Alice',
    breakTime: {
      start: '14-00',
      end: '14-00'
    },
  },
  {
    name: 'Steve',
    breakTime: {
      start: '10-00',
      end: '11-00'
    },
  },
  {
    name: 'Bob',
    breakTime: {
      start: '12-00',
      end: '13-00'
    },
  },
];

// приложение.component.html

<table mat-table [dataSource]="sortedData" multiTemplateDataRows 
       matSort (matSortChange)="sortItem($event)" 
       class="mat-elevation-z4 w-100">

  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef> Name </th>
    <td mat-cell *matCellDef="let item"> {{item.name}} </td>
  </ng-container>

  <ng-container matColumnDef="break">
    <th mat-header-cell *matHeaderCellDef mat-sort-header > Break </th>
    <td mat-cell *matCellDef="let element">
      {{element.breakTime.start}} - {{element.breakTime.end}}
    </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let element; columns: displayedColumns;"
      class="element-row"
      [class.example-expanded-row]="expandedElement === element"
      (click)="expandedElement = expandedElement === element ? null : element">
  </tr>
</table>
person Bruno Farias    schedule 10.10.2019