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

Можно ли как-то отключить автосортировку в таблице Angular, когда пользователь изменяет значение в столбце? Bcs сразу после изменения данные сортируются, когда есть активная сортировка по этому столбцу. Если я установил dataSource.sort = null, сортировка отключена, но сортировка данных вернулась к сортировке по умолчанию. Я хочу отсортировать данные только по щелчку заголовка столбца.


person niio    schedule 02.01.2020    source источник


Ответы (2)


Вы можете попробовать следующий подход. Я не знаю, как вы обновляете свою таблицу. Я просто использовал простой пример, чтобы показать вам, как вы можете отключить существующую сортировку в mat-table.

.ts

import {Component, OnInit, ViewChild} from '@angular/core';
import {MatSort} from '@angular/material/sort';
import {MatTableDataSource} from '@angular/material/table';

export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
}

const ELEMENT_DATA: PeriodicElement[] = [
  {position: 1, name: 'Hydrogen', weight: 100, symbol: 'H'},
  {position: 2, name: 'Helium', weight: 40, symbol: 'He'},
  {position: 3, name: 'Lithium', weight: 60, symbol: 'Li'},
  {position: 4, name: 'Beryllium', weight: 90, symbol: 'Be'},
  {position: 5, name: 'Boron', weight: 100, symbol: 'B'},
  {position: 6, name: 'Carbon', weight: 10, symbol: 'C'},
  {position: 7, name: 'Nitrogen', weight: 140, symbol: 'N'},
  {position: 8, name: 'Oxygen', weight: 150, symbol: 'O'},
  {position: 9, name: 'Fluorine', weight: 180, symbol: 'F'},
  {position: 10, name: 'Neon', weight: 20, symbol: 'Ne'},
];

/**
 * @title Table with sorting
 */
var i =11;
@Component({
  selector: 'table-sorting-example',
  styleUrls: ['table-sorting-example.css'],
  templateUrl: 'table-sorting-example.html',
})
export class TableSortingExample implements OnInit {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource = new MatTableDataSource(ELEMENT_DATA);

  @ViewChild(MatSort, {static: true}) sort: MatSort;

  ngOnInit() {
    this.dataSource.sort = this.sort;
  }
  AddNewItem(){
    this.dataSource.data = [...this.dataSource.data,{position: i, name: 'Neon', weight: 20, symbol: 'Ne'}];    
    this.sort.sort(
      {id:'',start:'asc',disableClear : false}
    )
    i++
  }  
}

.html

<button (click)="AddNewItem()">Add New Item</button>
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">

  <!-- Position Column -->
  <ng-container matColumnDef="position">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> No. </th>
    <td mat-cell *matCellDef="let element"> {{element.position}} </td>
  </ng-container>

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

  <!-- Weight Column -->
  <ng-container matColumnDef="weight">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Weight </th>
    <td mat-cell *matCellDef="let element"> {{element.weight}} </td>
  </ng-container>

  <!-- Symbol Column -->
  <ng-container matColumnDef="symbol">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Symbol </th>
    <td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

Вы можете найти рабочую ссылку здесь:

https://stackblitz.com/edit/angular-di4rp1

В компоненте после обновления источника данных просто добавьте эти строки, чтобы удалить существующую сортировку

this.sort.sort(
      {id:'',start:'asc',disableClear : false}
    )
person Mamta    schedule 02.01.2020

Я обнаружил, что после долгого часа борьбы с решением проблемы. Я переопределил метод сортировки по умолчанию, определив свой:

    this.dataSource.sortData = (
        dataArray: ServicePartnerCategory[],
        sortObj: MatSort
      ) => this.sortTableData(dataArray, sortObj);

В sortTableData я помещаю if isSortingEnabled и либо возвращаю отсортированный массив, либо предыдущий отсортированный массив. Это решает проблему, заключающуюся в том, что dataSource.sortData выполняется каждый раз, когда данные были изменены (см. Документацию). Мне также нужно было опускать заглавные буквы и каждый раз ставить пустые значения в конце, независимо от сортировки.

    sortTableData(
    dataArray: ServicePartnerCategory[],
    sortObj: MatSort
    ): ServicePartnerCategory[] {
    if (this.isSortingEnabled) {
      switch (sortObj.direction) {
        case 'asc':
          dataArray.sort((a, b) => this.getSortIndex(a, b, sortObj, 'asc'));
          break;
        case 'desc':
          dataArray.sort((a, b) => this.getSortIndex(a, b, sortObj, 'desc'));
          break;
        default:
          dataArray.sort(
            (a, b) =>
              this.dataSource.data.indexOf(a[sortObj.active]) -
              this.dataSource.data.indexOf(b[sortObj.active])
          );
          break;
      }
      this.lastSortArray = cloneDeep(dataArray);
    }

    return this.lastSortArray;
    }

Затем в функции изменения я установил для isSortingEnabled значение false. Эта функция изменения вызывается в form.valueChanges

    onChange: any = () => {
    this.isSortingEnabled = false;
    }

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

    onSortData($event) {
    this.isSortingEnabled = true;
     }

просто остальные функции:

    /**
    * Returns index wether the a should be sorted before or after b.
    * Capitals are omited
    * Empty value is always sorted to end of the list
    * @param a first object for compare
    * @param b second object to compare
    * @param sortObj name of the object property to sort by
    * @param sortDirection asc or desc
    */
    getSortIndex(
    a: ServicePartnerCategory,
    b: ServicePartnerCategory,
    sortObj: MatSort,
    sortDirection: string
    ): number {
    if (a[sortObj.active] === '' || a[sortObj.active] === null) return 1; //always move 
    //empty value to the end of the list
    if (sortDirection === 'asc')
      return this.getProperty(a, sortObj.active) >
        this.getProperty(b, sortObj.active)
        ? 1
        : -1;

    return this.getProperty(a, sortObj.active) <
      this.getProperty(b, sortObj.active)
      ? 1
      : -1;
  }
person niio    schedule 02.01.2020