【问题标题】:Angular material table server side filteringAngular 材质表服务器端过滤
【发布时间】:2021-07-19 03:32:05
【问题描述】:

我想制作 mat-table 以便在通过 HTTP 检索数据时进行过滤。我设法通过使用官方文档示例进行排序和分页。但我不知道如何在这个例子中添加过滤:

HTML:

    <div class="example-container mat-elevation-z8">
      <div class="example-loading-shade"
           *ngIf="isLoadingResults || isRateLimitReached">
        <mat-spinner *ngIf="isLoadingResults"></mat-spinner>
        <div class="example-rate-limit-reached" *ngIf="isRateLimitReached">
          GitHub's API rate limit has been reached. It will be reset in one minute.
        </div>
      </div>
    
      <div class="example-table-container">

    <table mat-table [dataSource]="filteredAndPagedIssues" class="example-table" matSort
           matSortActive="created" matSortDisableClear matSortDirection="desc"
           (matSortChange)="resetPaging()">
      <!-- Number Column -->
      <ng-container matColumnDef="number">
        <th mat-header-cell *matHeaderCellDef>#</th>
        <td mat-cell *matCellDef="let row">{{row.number}}</td>
      </ng-container>

      <!-- Title Column -->
      <ng-container matColumnDef="title">
        <th mat-header-cell *matHeaderCellDef>Title</th>
        <td mat-cell *matCellDef="let row">{{row.title}}</td>
      </ng-container>

      <!-- State Column -->
      <ng-container matColumnDef="state">
        <th mat-header-cell *matHeaderCellDef>State</th>
        <td mat-cell *matCellDef="let row">{{row.state}}</td>
      </ng-container>

      <!-- Created Column -->
      <ng-container matColumnDef="created">
        <th mat-header-cell *matHeaderCellDef mat-sort-header disableClear>
          Created
        </th>
        <td mat-cell *matCellDef="let row">{{row.created_at | date}}</td>
      </ng-container>

      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    </table>
      </div>
    
      <mat-paginator [length]="resultsLength" [pageSize]="30"></mat-paginator>
    </div>

TS:

    /**
     * @title Table retrieving data through HTTP
     */
    @Component({
      selector: 'table-http-example',
      styleUrls: ['table-http-example.css'],
      templateUrl: 'table-http-example.html',
    })
    export class TableHttpExample implements AfterViewInit {
      displayedColumns: string[] = ['created', 'state', 'number', 'title'];
      exampleDatabase: ExampleHttpDatabase | null;
      filteredAndPagedIssues: Observable<GithubIssue[]>;
    
      resultsLength = 0;
      isLoadingResults = true;
      isRateLimitReached = false;
    
      @ViewChild(MatPaginator) paginator: MatPaginator;
      @ViewChild(MatSort) sort: MatSort;
    
      constructor(private _httpClient: HttpClient) {}
    
      ngAfterViewInit() {
        this.exampleDatabase = new ExampleHttpDatabase(this._httpClient);
    
        this.filteredAndPagedIssues = merge(this.sort.sortChange, this.paginator.page)
          .pipe(
            startWith({}),
            switchMap(() => {
              this.isLoadingResults = true;
              return this.exampleDatabase!.getRepoIssues(
                this.sort.active, this.sort.direction, this.paginator.pageIndex);
            }),
            map(data => {
              // Flip flag to show that loading has finished.
              this.isLoadingResults = false;
              this.isRateLimitReached = false;
              this.resultsLength = data.total_count;
    
              return data.items;
            }),
            catchError(() => {
              this.isLoadingResults = false;
              // Catch if the GitHub API has reached its rate limit. Return empty data.
              this.isRateLimitReached = true;
              return observableOf([]);
            })
          );
      }
    
      resetPaging(): void {
        this.paginator.pageIndex = 0;
      }
    }
    
    export interface GithubApi {
      items: GithubIssue[];
      total_count: number;
    }
    
    export interface GithubIssue {
      created_at: string;
      number: string;
      state: string;
      title: string;
    }
    
    /** An example database that the data source uses to retrieve data for the table. */
    export class ExampleHttpDatabase {
      constructor(private _httpClient: HttpClient) {}
    
      getRepoIssues(sort: string, order: string, page: number): Observable<GithubApi> {
        const href = 'https://api.github.com/search/issues';
        const requestUrl =
            `${href}?q=repo:angular/components&sort=${sort}&order=${order}&page=${page + 1}`;
    
        return this._httpClient.get<GithubApi>(requestUrl);
      }
    }

如何在这个例子中添加过滤?我想只在客户端进行排序、过滤和分页以使其正常工作,但我认为如果有人可以解决这个问题,最好在服务器端执行此操作。

【问题讨论】:

  • @Eliseo 谢谢。但是为什么要使用 debounceTime()?
  • 当您订阅 formcontrol.valueChange 时,每次更改时都会发出更改。因此,如果您快速键入“ab”(在 200 毫秒内)发射两次,则 debounceTime 会避免它。
  • @Eliseo 我明白了。我现在唯一的问题是我正在使用带有 OData 的 .NET Core 服务器端。所以他们停止更新 OData,所以我无法使用查询选项获得总项目数。使用您的示例,我不理解const getLength = this.filter.valueChanges.pipe(... 的一部分。抱歉,我对这整个 Angular 很陌生。
  • @Eliseo 我设法让它工作。非常感谢。

标签: angular typescript angular-material mat-table


【解决方案1】:

例如,如果您想根据单选按钮更改进行过滤,您可以:

  1. 添加到您的模板:
<mat-radio-group (change)="filterChanged.emit($event)" [(ngModel)]="filterString">
    <mat-radio-button value="A">A</mat-radio-button>
    <mat-radio-button value="B">B</mat-radio-button>
</mat-radio-group>
  1. 添加您的组件:
filterString = 'A';
filterChanged = new EventEmitter<MatRadioChange>();
  1. 组件的变化:
this.filteredAndPagedIssues = merge(this.sort.sortChange, this.paginator.page)` 

this.filteredAndPagedIssues = merge(this.sort.sortChange, this.paginator.page, this.filterChanged)

然后您可以使用this.filterString 进行服务器请求。

【讨论】:

    猜你喜欢
    • 2016-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-11
    • 2021-09-19
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    • 2018-07-06
    相关资源
    最近更新 更多