Clasificación predeterminada en material angular - encabezado de clasificación

85

¿Cómo puedo cambiar el código de material angular a continuación, de modo que la tabla de datos esté ordenada por la columna 'nombre', en orden ascendente de forma predeterminada? Se debe mostrar la flecha (que indica la dirección de clasificación actual).

Esto es lo que quiero lograr:

ingrese la descripción de la imagen aquí

Codigo original:

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

Estaba intentando algo como esto, pero no funciona (no se muestra ninguna flecha, no está ordenada)

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

Aquí está el enlace a Plunker

Jacek Kościesza
fuente
Podría llamar this.sortData({active: "name", direction: "asc"})al ngOnInitcheque plunker
Pankaj Parkar
1
@PankajParkar No es la solución correcta. La tabla está ordenada, pero el encabezado de clasificación no lo sabe y la flecha (que indica la dirección de clasificación actual) no se muestra.
Jacek Kościesza

Respuestas:

134

Estás confundiendo matSortStarta matSortDirection.

Prueba esto:

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

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

matSortStart se puede usar para revertir el ciclo usado al ordenar (por ejemplo, cuando el usuario hace clic para ordenar, comienza en desc en lugar de asc).

Andrew Seguin
fuente
4
Este método funciona solo por primera vez. Después de que se cambió el origen de datos de la tabla, intento restablecer el matSortActivey, matSortDirectionpero no se muestra la flecha pequeña
Gil Epshtain
La muestra parece que ya no funciona, hice una nueva: stackblitz.com/edit/angular-defaultsort?file=src/app/…
Ben
45

Puede ordenar la tabla mediante programación invocando el sort(Sortable)método de la fuente de datos. Suponiendo que tiene una dataSourcepropiedad de componente para la fuente de datos:

// 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;
Nino Filiu
fuente
1
Esto es lo que estoy buscando, pero el único problema es que desencadena el matSortChangeevento. ¿Hay alguna forma de configurar la ordenación sin desencadenar el evento?
rain01
No. Así es como se llama al género. ¿Por qué no desea que se active el evento matSortChange?
Nino Filiu
1
porque lo tengo configurado para actualizar una cookie con asc/ descde una columna y si se llama cada vez que se carga la página, entonces cada vez será diferente
rain01
16
@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);

Deberia trabajar. manifestación

Y para mostrar la flecha de dirección de clasificación, agregue el siguiente CSS (solución alternativa)

th.mat-header-cell .mat-sort-header-container.mat-sort-header-sorted .mat-sort-header-arrow {
    opacity: 1 !important;
    transform: translateY(0) !important;
}
Aman Madiiarbekov
fuente
2
Proporcione algunas explicaciones junto con su código, para que el usuario posterior pueda seguir sus ideas / código más fácilmente.
HansHirse
1
Utilicé la ordenación de Nino y la solución CSS aquí para que mi ordenación configurada mediante programación muestre la flecha.
bts
En angular 7 acabo de configurar this.sort = {active: 'nombre', dirección: 'desc'}; y no tuve que agregar ningún cambio de CSS para que la flecha estuviera activa.
Nick Gallimore
Nick Gallimore, ¿quizás estás agregando tu css no en el lugar correcto? intente agregarlo en un archivo css global principal (puede estar en assets / css / ... css)
Aman Madiiarbekov
10

Actualización de material (probado con v7.3):

@ViewChild(MatSort) matSort: MatSort;

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

Esto también actualizará la mat-sort-headerflecha 'sin ninguna solución.

sschmid
fuente
2

También puede vincular las propiedades de clasificación de la tabla de mat a la variable de su componente.

Como dice @Andrew Seguin:

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

Esta es la forma correcta de establecer la clasificación predeterminada si sabe cuál es esa.

En caso de que obtenga la clasificación desde otro lugar (en mi caso, desde los parámetros de la cadena de consulta), también puede hacerlo así (las flechas de clasificación funcionan perfectamente aquí):

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


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

¿Quizás ha intentado llamar en el inicio de la página a la función de clasificación forzada en nombre y dirección?

     ngOnInit() {
    let defSort: Sort = {};
    defSort.direction = 'asc';
    defSort.active = 'name';
    this.sortData(defSort);
  }
federico scamuzzi
fuente
5
No es la solución correcta. La tabla está ordenada, pero el encabezado de clasificación no lo sabe y la flecha (que indica la dirección de clasificación actual) no se muestra
Jacek Kościesza
1

En mi caso, la clasificación no funcionaba porque matColumDef id y mat-cell var es diferente

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

después de hacer cambios matColumnDef = "firstName" a matColumnDef = " name " que es el mismo que el elemento. nombre

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

Funciona bien para mí

Yogesh Borkhade
fuente
0

Tuve que hacer una ordenación predeterminada al cargar

const matSort = { id: defaultSort.name } as MatSortable;
this.sort.direction = defaultSort.sort === 'asc' ? '' : defaultSort.sort === 'desc' ? 'asc' : 'desc' as SortDirection;
this.sort.sort(matSort);
Illia
fuente
0

La respuesta de @Andrew Seguin (primera respuesta aceptada) hizo el truco visual para mí, pero no resolvió la tabla.

Mi solución es usar el código html proporcionado por @Andrew Seguin y llamar al método sortData (sort: Sort) yo mismo, pero ¿cómo hacerlo? Como se especifica en la documentación , `` Ordenar '' es una interfaz que tiene dos propiedades, activa y dirección, y la interfaz debe tener un aspecto parecido a esto:

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

Entonces, el truco es llamar al método sortData (sort: Sort) en ngOnInit de la siguiente manera:

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

El código HTML es como en la respuesta aceptada ;-) Espero que esto ayude a alguien, Alex

Ejemplos de documentación

Alex B
fuente