角度材料表分页,排序和过滤

时间:2018-01-13 17:49:34

标签: angular angular-material

我试图使用角度材料标签进行分页,过滤和排序,但我遇到了这个例外:

  

错误类型错误:您提供了' undefined'预期流的地方。   您可以提供Observable,Promise,Array或Iterable。

可能是什么问题?

user.component.ts

export class UserComponent implements OnInit {

  dataSource: UserDataSource;
  displayedColumns = ['name', 'email', 'phone', 'company'];
  myData: User[];

  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;
  @ViewChild('filter') filter: ElementRef;

  constructor(private userService: UserService) { }

  ngOnInit() {
    this.userService.getUser()
      .subscribe(res => {
        this.myData = res;
      })
    this.dataSource = new UserDataSource(this.myData, this.paginator, this.sort);
    Observable.fromEvent(this.filter.nativeElement, 'keyup')
      .debounceTime(150)
      .distinctUntilChanged()
      .subscribe(() => {
        if (!this.dataSource) { return; }
        this.dataSource.filter = this.filter.nativeElement.value;
      });
  }
}

UserDataSource

export class UserDataSource extends DataSource<any> {
  _filterChange = new BehaviorSubject('');
  get filter(): string { return this._filterChange.value; }
  set filter(filter: string) { this._filterChange.next(filter); }

  filteredData: User[] = [];
  renderedData: User[] = [];
  constructor(private data: User[], private paginator: MatPaginator, private sort: MatSort) {
    super();
    this._filterChange.subscribe(() => this.paginator.pageIndex = 0);

  }
  connect(): Observable<User[]> {
    const displayDataChanges = [
      this.data,
      this.sort.sortChange,
      this._filterChange,
      this.paginator.page,
    ];
    return Observable.merge(...displayDataChanges).map(() => {
      // Filter data
      this.filteredData = this.data.slice().filter((item: User) => {
        let searchStr = (item.name).toLowerCase();
        return searchStr.indexOf(this.filter.toLowerCase()) != -1;
      });

      const sortedData = this.sortData(this.filteredData.slice());

      const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
      this.renderedData = sortedData.splice(startIndex, this.paginator.pageSize);
      return this.renderedData;
    });

  }
  disconnect() { }

  sortData(data: User[]): User[] {
    if (!this.sort.active || this.sort.direction == '') { return data; }

    return data.sort((a, b) => {
      let propertyA: number | string = '';
      let propertyB: number | string = '';

      switch (this.sort.active) {
        case 'name': [propertyA, propertyB] = [a.name, b.name]; break;
        case 'email': [propertyA, propertyB] = [a.email, b.email]; break;
        case 'phone': [propertyA, propertyB] = [a.phone, b.phone]; break;
        case 'company': [propertyA, propertyB] = [a.company.name, b.company.name]; break;
      }

      let valueA = isNaN(+propertyA) ? propertyA : +propertyA;
      let valueB = isNaN(+propertyB) ? propertyB : +propertyB;

      return (valueA < valueB ? -1 : 1) * (this.sort.direction == 'asc' ? 1 : -1);
    });
  }
}

1 个答案:

答案 0 :(得分:0)

我的HTML代码是:

<div>
    <div class="example-header" >
        <mat-input-container floatPlaceholder="never">
          <input matInput #filter placeholder="Filter users">
        </mat-input-container>
      </div>
    <mat-table [dataSource]="dataSource" matSort>
      <ng-container matColumnDef="name">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
        <mat-cell *matCellDef="let user"> {{user.name}} </mat-cell>
      </ng-container>
      <ng-container matColumnDef="email">
        <mat-header-cell *matHeaderCellDef mat-sort-header> E-Mail </mat-header-cell>
        <mat-cell *matCellDef="let user"> {{user.email}} </mat-cell>
      </ng-container>
      <ng-container matColumnDef="phone">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Phone </mat-header-cell>
      </ng-container>
      <ng-container matColumnDef="company">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Company </mat-header-cell>
        <mat-cell *matCellDef="let user"> {{user.company.name}} </mat-cell>
      </ng-container>
      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
    </mat-table>
    <div class="example-no-results"
    [style.display]="dataSource?.renderedData.length == 0 ? '' : 'none'">
 No users found matching filter.
</div>

<mat-paginator #paginator 
             [length]="dataSource?.filteredData.length"
             [pageIndex]="0"
             [pageSize]="25"
             [pageSizeOptions]="[5, 10, 25, 100]">
</mat-paginator>
  </div>