首页 > 解决方案 > 为什么 matSort 不能处理异步数据

问题描述

我尝试使用异步数据为我的表实现 matSort,但它不起作用,我正在寻找解决方案。我看到了按钮,但它不起作用。用户在输入中键入国家名称,然后从我放入表中的 API 返回一个数组。

角度/cli:9.1.3 角度/材料:10.0.1

这是我的代码:

HTML

<form  class="example-form" [formGroup]="searchForm" (ngSubmit)="search()"  fxLayoutAlign="center center" >
    <mat-form-field class="example-full-width"  style="background-color: #fff; opacity: 0.9; margin-right: 20px;">
        <input #nameInput type="text"
                placeholder="Country"
                aria-label="Number"
                matInput
                formControlName="countryName"
                [matAutocomplete]="auto" >
                <mat-icon (click)="nameInput.value=''" matSuffix>clear</mat-icon>
        <mat-autocomplete #auto="matAutocomplete">
            <mat-option *ngFor="let country of filteredCountries | async" [value]="country">
            {{country}}
            </mat-option>
        </mat-autocomplete>
    </mat-form-field>
    <button mat-fab color="primary" aria-label="Example icon button with a delete icon" [disabled]="!searchForm.valid">
        <mat-icon>search</mat-icon>
    </button>
</form>
<div [hidden]="!isSearched" class="mat-elevation-z8" fxLayout="column" fxLayoutAlign="center center">

  <table mat-table [dataSource]="dataSource" matSort matSortActive="date" matSortDirection="desc">
  
    <ng-container matColumnDef="date">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Date </th>
      <td mat-cell *matCellDef="let element"> {{element.Date |date:'shortDate'}} </td>
    </ng-container>
  
    <ng-container matColumnDef="confirmed">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Total Confirmed </th>
      <td mat-cell *matCellDef="let element"> {{element.Confirmed| number}} </td>
    </ng-container>

    <ng-container matColumnDef="active">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Total Active </th>
      <td mat-cell *matCellDef="let element"> {{element.Active| number}} </td>
    </ng-container>
  
    <ng-container matColumnDef="recovered">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Total Recovered </th>
      <td mat-cell *matCellDef="let element"> {{element.Recovered| number}} </td>
    </ng-container>

    <ng-container matColumnDef="deaths">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Total Deaths </th>
      <td mat-cell *matCellDef="let element"> {{element.Deaths| number}} </td>
    </ng-container>
  
    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
  

  </table>
  
</div>
<mat-paginator [hidden]="!isSearched" #paginator [pageSizeOptions]="[5, 10, 20]"></mat-paginator>

TS:

export class CountryHistoryComponent implements OnInit {
  searchForm:FormGroup;
  filteredCountries: Observable<string[]>;
  countries=[];
  isSearched=false;
  displayedColumns: string[] = [ 'date', 'confirmed', 'active', 'recovered','deaths'];
  @ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
  @ViewChild(MatSort, {static: false}) sort: MatSort;
  dataSource: { data: any; paginator: MatPaginator; sort: MatSort; };
  
  constructor(private statsService:StatsService) { }

  ngOnInit(): void {
    this.statsService.getCountries();
    this.statsService.countries.subscribe(res=>{
      this.countries=res.map(country=>{
        return country['Country'];
      })
      this.countries.sort();
      console.log(this.countries);
    })
    this.searchForm=new FormGroup({
      countryName:new FormControl('',{validators:[Validators.required]})
    })
    this.filteredCountries = this.searchForm.controls['countryName'].valueChanges
      .pipe(
        startWith(''),
        map(value => this._filter(value))
      );

    
  }

  private _filter(value: string): string[] {
    const filterValue = value.toLowerCase();
    return this.countries.filter(countryName => countryName.toLowerCase().includes(filterValue));
  }
  
  

  search(){
    console.log(this.searchForm.controls['countryName'].value);
    this.statsService.getTotalByCountry(this.searchForm.controls['countryName'].value);
    this.statsService.countryHistory.subscribe(res=>{
      this.isSearched=true;
      this.dataSource=new MatTableDataSource(res.reverse());
      //this.dataSource.data=res.reverse();
      this.paginator.firstPage();
      this.dataSource.paginator = this.paginator;
      this.dataSource.sort = this.sort;
    })
  }

  


}

标签: javascripthtmlangulartypescriptangular-material

解决方案


我认为您只需要处理排序结果。例如,您可以捕捉matSortChange将为您提供信息的事件。它将返回您的活动列值displayedColumns和方向:ascdesc。因此,更新控制器中的一些值并使用这些值重播查询(通常使用查询参数)。

  <table mat-table [dataSource]="dataSource" (matSortChange)="sortChange($event)" matSort>
  sortChange(sortEvent: Sort): void {
    this.sortField = sortEvent.active;
    this.sortDirection = sortEvent.direction;
    this.getItems();
  }

使用排序参数获取数据的方法可能在哪里getItems(),例如:

getItems() {
    this.itemsService.getItems(
      this.page, this.pageSize, this.sortField, this.sortDirection)
      .subscribe(
        data => {
          this.dataSource = new MatTableDataSource<Item>(data.data.items);
          this.length = data.data.total;
          this.queryDone = true;
        })
  }

推荐阅读