Сортировка по умолчанию в Angular Material - Сортировка заголовка

89

Как я могу изменить код Angular Material ниже, чтобы таблица данных была отсортирована по столбцу «имя» в порядке возрастания по умолчанию. Стрелка (указывающая текущее направление сортировки) должна быть отображена.

Вот чего я хочу добиться:

введите описание изображения здесь

Исходный код:

<table matSort (matSortChange)="sortData($event)">
  <tr>
    <th mat-sort-header="name">Dessert (100g)</th>
    <th mat-sort-header="calories">Calories</th>
    <th mat-sort-header="fat">Fat (g)</th>
    <th mat-sort-header="carbs">Carbs (g)</th>
    <th mat-sort-header="protein">Protein (g)</th>
  </tr>

  <tr *ngFor="let dessert of sortedData">
    <td>{{dessert.name}}</td>
    <td>{{dessert.calories}}</td>
    <td>{{dessert.fat}}</td>
    <td>{{dessert.carbs}}</td>
    <td>{{dessert.protein}}</td>
  </tr>
</table>

Я пробовал что-то подобное, но это не работает (стрелка не отображается, не отсортирована)

<table matSort (matSortChange)="sortData($event)" matSortActive="name" matSortStart="asc" matSortDisableClear>

Вот ссылка на Plunker

Яцек Кошича
источник
Могу позвонить this.sortData({active: "name", direction: "asc"})на ngOnInitчек- плункер
Панкадж Паркар
1
@PankajParkar Это неправильное решение. Таблица отсортирована, но заголовок сортировки не знает об этом и стрелка (указывающая текущее направление сортировки) не отображается.
Яцек

Ответы:

138

Вы ошибаетесь matSortStartзаmatSortDirection .

Попробуй это:

<table matSort (matSortChange)="sortData($event)" matSortActive="name" matSortDirection="asc" matSortDisableClear>

https://plnkr.co/edit/sg0hC5d8LTjLKhbH9Eug?p=preview

matSortStart может использоваться для изменения цикла, используемого при сортировке (например, когда пользователь щелкает для сортировки, он начинается с desc вместо asc).

Эндрю Сегин
источник
5
Этот метод работает только впервые. После изменения источника данных таблицы я пытаюсь переустановить matSortActiveи, matSortDirectionно маленькая стрелка не отображается
Гил Эпштейн
Образец больше не работает, я сделал новый: stackblitz.com/edit/angular-defaultsort?file=src/app/…
Бен,
45

Вы можете программно отсортировать таблицу, вызвав sort(Sortable)метод источника данных. Предполагая, что у вас есть dataSourceсвойство компонента для источника данных:

// to put next to the class fields of the component
@ViewChild(MatSort) sort: MatSort

// to put where you want the sort to be programmatically triggered, for example inside ngOnInit
this.sort.sort(({ id: 'name', start: 'asc'}) as MatSortable);
this.dataSource.sort = this.sort;
Нино Филиу
источник
1
Это то, что я ищу, но единственная проблема в том, что это запускает matSortChangeсобытие. Есть ли способ установить сортировку без запуска события?
rain01
Нет. Так называется сортировка. Почему вы не хотите, чтобы запускалось событие matSortChange?
Нино Филиу
1
потому что у меня он настроен на обновление файла cookie с помощью asc/ descстолбца, и если он вызывается каждый раз при загрузке страницы, то каждый раз он будет другим
rain01
17
@ViewChild(MatSort) sort: MatSort;

this.dataSource.sort = this.sort;

const sortState: Sort = {active: 'name', direction: 'desc'};
this.sort.active = sortState.active;
this.sort.direction = sortState.direction;
this.sort.sortChange.emit(sortState);

должно сработать. демо

И чтобы показать стрелку направления сортировки, добавьте следующий css (обходной путь)

th.mat-header-cell .mat-sort-header-container.mat-sort-header-sorted .mat-sort-header-arrow {
    opacity: 1 !important;
    transform: translateY(0) !important;
}
Аман Мадиярбеков
источник
4
Пожалуйста, предоставьте некоторые пояснения вместе с вашим кодом, чтобы позже пользователь мог легче следовать вашим идеям / коду.
HansHirse
1
Я использовал сортировку от Nino и обходной путь CSS, чтобы программно установленная сортировка отображала стрелку.
bts
В angular 7 я просто установил this.sort = {active: 'name', direction: 'desc'}; и мне не нужно было добавлять какие-либо изменения CSS, чтобы стрелка была активной.
Ник
Ник Галлимор, может быть, вы добавляете свой css не в нужное место? попробуйте добавить его в главный глобальный файл css (он может быть в assets / css / ... css)
Аман Мадиярбеков
10

Обновление для материалов (проверено с v7.3):

@ViewChild(MatSort) matSort: MatSort;

private someMethod(): void {
  this.matSort.sort({ id: 'columnName', start: 'asc', disableClear: false });
}

Это также обновит mat-sort-headerстрелку без какого-либо обходного пути

сшмид
источник
3

Вы также можете привязать свойства сортировки mat-table к переменной вашего компонента.

Как говорит @Andrew Seguin:

<table matSort matSortActive="name" matSortDirection="asc">

Это правильный способ установить сортировку по умолчанию, если вы знаете, какая это.

В случае, если вы получаете сортировку откуда-то еще (в моем случае из параметров строки запроса), вы также можете сделать это следующим образом (здесь отлично работают стрелки сортировки):

sortDirection: 'name',  // this can be changed or filled in any time
sortProperty: 'asc',


<mat-table matSort [matSortActive]="sortProperty" [matSortDirection]="sortDirection">
Милош
источник
1

Может быть, вы пытались вызвать при инициализации страницы функцию сортировки по имени и направлению?

     ngOnInit() {
    let defSort: Sort = {};
    defSort.direction = 'asc';
    defSort.active = 'name';
    this.sortData(defSort);
  }
Федерико Скамуцци
источник
6
Это неправильное решение. Таблица отсортирована, но заголовок сортировки не знает об этом, а стрелка (указывающая текущее направление сортировки) не отображается
Яцек
1

В моем случае сортировка не работала, потому что matColumDef id и mat-cell var разные

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

после внесения изменений matColumnDef = "firstName" на matColumnDef = " name ", которое совпадает с элементом. имя

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

Он отлично работает для меня

Йогеш Боркхаде
источник
0

Мне пришлось сделать сортировку по умолчанию при загрузке

const matSort = { id: defaultSort.name } as MatSortable;
this.sort.direction = defaultSort.sort === 'asc' ? '' : defaultSort.sort === 'desc' ? 'asc' : 'desc' as SortDirection;
this.sort.sort(matSort);
Илья
источник
0

Ответ от @Andrew Seguin (первый и принятый ответ) сделал для меня визуальный трюк, но он не сортировал таблицу.

Мое решение - использовать html-код, предоставленный @Andrew Seguin, и сам вызвать метод sortData (sort: Sort) , но как это сделать? Как указано в документации , «Сортировка» - это интерфейс, который имеет два свойства: активное и направление, и интерфейс должен выглядеть примерно так:

export interface Sort {
   active:string //The id/name of the column being sorted
   direction:string //asc or dsc depending on the use case (The sort direction)
}

Итак, уловка состоит в том, чтобы вызвать метод sortData (sort: Sort) в ngOnInit следующим образом:

ngOnInit(){
    //Do some nitialization
    this.sortData({active:'name', direction:'asc'});
}

sortData(sort: Sort) {
    //Your sorting algorithm (see examples in documentation, link above and at the bottom)
}

Код HTML такой же, как в принятом ответе ;-) Надеюсь, это поможет кому-нибудь, Алекс

Примеры документации

Алекс Б
источник
0

Есть несколько факторов, влияющих на поведение. В основном это использование MatTableDataSource по сравнению с производной от DataSource, созданной вручную. . Таким образом, в одних случаях разные решения могут работать, а в других - нет.

В любом случае, это старая ошибка, о которой хорошо сказано на GitHub . Пожалуйста, проголосуйте за эту проблему GitHub, чтобы привлечь внимание команды Angular.

Самое надежное решение, опубликованное в этом потоке GitHub ( ссылка ), - это вызвать следующий метод применения порядка сортировки:

public setSort(id: string, start?: 'asc' | 'desc') {
    start = start || 'asc';
    const matSort = this.dataSource.sort;
    const toState = 'active';
    const disableClear = false;

    //reset state so that start is the first sort direction that you will see
    matSort.sort({ id: null, start, disableClear });
    matSort.sort({ id, start, disableClear });

    //ugly hack
    (matSort.sortables.get(id) as MatSortHeader)._setAnimationTransitionState({ toState });
}
Алекс Клаус
источник