Ordinamento predefinito in materiale angolare - Ordina intestazione


89

Come posso cambiare il codice del materiale angolare di seguito, in modo che la tabella dati sia ordinata per colonna "nome", in ordine crescente per impostazione predefinita. Deve essere visualizzata la freccia (che indica la direzione di ordinamento corrente).

Questo è ciò che voglio ottenere:

inserisci qui la descrizione dell'immagine

Codice originale:

<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>

Stavo provando qualcosa di simile, ma non funziona (nessuna freccia visualizzata, non ordinata)

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

Ecco il collegamento a Plunker


Potrei chiamare this.sortData({active: "name", direction: "asc"})il ngOnInitcheck plunker
Pankaj Parkar

1
@PankajParkar Non è la soluzione corretta. La tabella è ordinata, ma l'intestazione di ordinamento non ne è a conoscenza e la freccia (che indica la direzione di ordinamento corrente) non viene visualizzata.
Jacek Kościesza

Risposte:


138

Stai scambiando matSortStartper matSortDirection.

Prova questo:

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

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

matSortStart può essere utilizzato per invertire il ciclo utilizzato durante l'ordinamento (ad esempio, quando l'utente fa clic per ordinare, inizia da desc invece che asc).


5
Questo metodo funziona solo per la prima volta. Dopo che il dataSource della tabella è stato modificato, provo a reimpostare il matSortActivee matSortDirectionma la piccola freccia non viene visualizzata
Gil Epshtain

L'esempio sembra non funzionare più, ne ho creato uno nuovo: stackblitz.com/edit/angular-defaultsort?file=src/app/…
Ben

45

È possibile ordinare la tabella a livello sort(Sortable)di codice richiamando il metodo dell'origine dati. Supponendo che tu abbia una dataSourceproprietà del componente per l'origine dati:

// 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
Questo è un po 'quello che sto cercando, ma l'unico problema è che innesca l' matSortChangeevento. C'è un modo per impostare l'ordinamento senza attivare l'evento?
pioggia 01

No. È così che viene chiamato l'ordinamento. Perché non vuoi che venga attivato l'evento matSortChange?
Nino Filiu

1
perché l'ho impostato per aggiornare un cookie con asc/ descdi una colonna e se viene chiamato ogni volta che la pagina viene caricata, ogni volta sarà diverso
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);

dovrebbe funzionare. demo

E per mostrare la freccia di direzione dell'ordinamento, aggiungi il css successivo (soluzione alternativa)

th.mat-header-cell .mat-sort-header-container.mat-sort-header-sorted .mat-sort-header-arrow {
    opacity: 1 !important;
    transform: translateY(0) !important;
}

4
Fornisci alcune spiegazioni insieme al tuo codice, in modo che l'utente successivo possa seguire le tue idee / codice più facilmente.
HansHirse

1
Ho usato l'ordinamento di Nino e la soluzione CSS qui per ottenere l'ordinamento impostato a livello di programmazione per mostrare la freccia.
bts

In angular 7 ho appena impostato this.sort = {active: 'name', direction: 'desc'}; e non ho dovuto aggiungere alcuna modifica CSS affinché la freccia fosse attiva.
Nick Gallimore

Nick Gallimore forse stai aggiungendo il tuo css non nel posto corretto? prova ad aggiungerlo in un file css globale principale (può essere in assets / css / ... css)
Aman Madiiarbekov

10

Aggiornamento per materiale (testato con v7.3):

@ViewChild(MatSort) matSort: MatSort;

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

Ciò aggiornerà anche la mat-sort-headerfreccia di senza alcuna soluzione alternativa


3

Puoi anche associare le proprietà di ordinamento della tabella mat alla variabile componente.

Come dice @Andrew Seguin:

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

Questo è il modo corretto per impostare l'ordinamento predefinito se sai qual è quello.

Nel caso in cui ottieni l'ordinamento da qualche altra parte (nel mio caso dai parametri della stringa di query), puoi anche farlo in questo modo (le frecce di ordinamento funzionano perfettamente qui):

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


<mat-table matSort [matSortActive]="sortProperty" [matSortDirection]="sortDirection">

1

Forse hai provato a chiamare all'inizio della pagina la funzione di ordinamento forzata su nome e direzione?

     ngOnInit() {
    let defSort: Sort = {};
    defSort.direction = 'asc';
    defSort.active = 'name';
    this.sortData(defSort);
  }

6
Non è una soluzione corretta. La tabella è ordinata, ma l'intestazione di ordinamento non lo sa e la freccia (che indica la direzione di ordinamento corrente) non viene visualizzata
Jacek Kościesza

1

Nel mio caso l'ordinamento non funzionava perché matColumDef id e mat-cell var sono diversi

<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>

dopo aver apportato le modifiche matColumnDef = "firstName" a matColumnDef = " name " che è uguale all'elemento. nome

    <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>

per me funziona bene


0

Ho dovuto fare l'ordinamento predefinito al caricamento

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

La risposta di @Andrew Seguin (prima e accettata risposta) ha fatto il trucco visivo per me, ma non ha ordinato la tabella.

La mia soluzione è utilizzare il codice html fornito da @Andrew Seguin e chiamare il metodo sortData (sort: Sort) da solo, ma come farlo? Come specificato nella documentazione , `` Sort '' è un'interfaccia che ha due proprietà, active e direction e l'interfaccia deve avere un aspetto simile a questo:

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)
}

Quindi il trucco è chiamare il metodo sortData (sort: Sort) in ngOnInit come segue:

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)
}

Il codice HTML è come nella risposta accettata ;-) Spero che questo aiuti chiunque, Alex

Esempi di documentazione


0

Ci sono diversi fattori che contribuiscono che influenzano il comportamento. Principalmente è l'uso di MatTableDataSource rispetto a un derivato artigianale di DataSource . Quindi soluzioni diverse possono funzionare in alcuni casi e non in altri.

Ad ogni modo, è un vecchio bug che è stato ben coperto su GitHub . Si prega di votare a favore del problema di GitHub per attirare l'attenzione del team di Angular.

La soluzione più durevole pubblicata su quel thread GitHub ( link ) consiste nel chiamare il seguente metodo sull'applicazione di un ordinamento:

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 });
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.