为什么材料表排序或分页都不起作用?

时间:2019-01-13 11:40:08

标签: angular angular-material

我得到了一些支持,将其余api调用中的数据馈送到Materialdata表中。不幸的是,分页或排序确实有效。我的假设是初始化某种程度上是错误的。 加载页面时出现错误TypeError:无法读取控制台中未定义的属性'data'。 1-2秒后,我看到了其余的响应,并且数据显示在表中,但是排序还是分页都无法正常进行。单击表标题对数据进行排序时,没有其他错误。

accountlist-datasource.ts

import { Account } from './../_services/accounts';
import { DataSource } from '@angular/cdk/collections';
import { MatPaginator, MatSort } from '@angular/material';
import { map } from 'rxjs/operators';
import { Observable, of as observableOf, merge } from 'rxjs';

export class AccountlistDataSource extends DataSource<Account> {
data: Account[];

  constructor(private paginator: MatPaginator, private sort: MatSort) {
    super();
  }

  connect(): Observable<Account[]> {
    const dataMutations = [
      observableOf(this.data),
      this.paginator.page,
      this.sort.sortChange
    ];

    this.paginator.length = this.data.length;

    return merge(...dataMutations).pipe(map(() => {
      return this.getPagedData(this.getSortedData([...this.data]));
    }));
  }

  disconnect() {}

  private getPagedData(data: Account[]) {
    const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
    return data.splice(startIndex, this.paginator.pageSize);
  }

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

    return data.sort((a, b) => {
      const isAsc = this.sort.direction === 'asc';
      switch (this.sort.active) {
        case 'Name': return compare(a.Name, b.Name, isAsc);
        case 'ID': return compare(+a.ID, +b.ID, isAsc);
        default: return 0;
      }
    });
  }
}

function compare(a, b, isAsc) {
  return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}

accountlist.component.html

<h1>Institutions / Customer / Accounts</h1>
<div class="mat-elevation-z8">
  <table mat-table class="full-width-table" [dataSource]="accounts.data.Documents" matSort aria-label="Elements">

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

    <ng-container matColumnDef="Account Number">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Institution ID</th>
      <td mat-cell *matCellDef="let row">{{row['Account Number']}}</td>
    </ng-container>

    <ng-container matColumnDef="SHS_SAP_SOLD_TO">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>SAP Number</th>
        <td mat-cell *matCellDef="let row">{{row.SHS_SAP_SOLD_TO}}</td>
    </ng-container>

    <ng-container matColumnDef="Country">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Country</th>
        <td mat-cell *matCellDef="let row">{{row.Country}}</td>
    </ng-container>

    <ng-container matColumnDef="State/Province">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>State</th>
        <td mat-cell *matCellDef="let row">{{row['State/Province']}}</td>
    </ng-container>

    <ng-container matColumnDef="City">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>City</th>
        <td mat-cell *matCellDef="let row">{{row.City}}</td>
    </ng-container>

    <ng-container matColumnDef="Postal Code">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Postal Code</th>
      <td mat-cell *matCellDef="let row">{{row['Postal Code']}}</td>
    </ng-container>

    <ng-container matColumnDef="Address 1">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Address</th>
        <td mat-cell *matCellDef="let row">{{row['Address 1']}}</td>
    </ng-container>

    <ng-container matColumnDef="Created Date">
        <th mat-header-cell *matHeaderCellDef mat-sort-header>Created Date</th>
        <td mat-cell *matCellDef="let row">{{row['Created Date']}}</td>
    </ng-container>

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

  <mat-paginator #paginator
      [length]="accounts.data.length"
      [pageIndex]="0"
      [pageSize]="50"
      [pageSizeOptions]="[25, 50, 100, 250]">
  </mat-paginator>
</div>

Accounts.ts

export interface Account {
  Name: string;
  ID: string;
  City: string;
  Country: string;
  SHS_SAP_SOLD_TO: string;
  'Account Number': string;
  'Postal Code': string;
  'Address 1': string;
  'Address 2': string;
  'State/Province': string;
}

accountslist.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator, MatSort } from '@angular/material';
import { AccountlistDataSource } from './accountlist-datasource';
import { AzureService } from './../_services/azure.service';

@Component({
  selector: 'app-accountlist',
  templateUrl: './accountlist.component.html',
  styleUrls: ['./accountlist.component.css']
})
export class AccountlistComponent implements OnInit {
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;
  dataSource: AccountlistDataSource | null;
  displayedColumns = [
    'Name', 'Account Number', 'SHS_SAP_SOLD_TO', 'Country', 'State/Province', 'City', 'Postal Code', 'Address 1', 'Created Date'];

  public accounts: any;
  isLoading = true;

  constructor(private azureService: AzureService) {
  }

  RenderDataTable() {
    this.azureService.getAccountsAzure()
      .subscribe(
      res => {
        this.accounts = new AccountlistDataSource(this.paginator, this.sort);
        this.accounts.data = res as Account[];
        console.log(this.accounts);
        this.isLoading = false;
      },
      error => {
        console.log('There was an error while retrieving data !!!' + error);
      });
  }

  ngOnInit() {
   this.RenderDataTable();
  }
}

1 个答案:

答案 0 :(得分:0)

  • 我不确定您的代码中到底发生了什么,因为我看不到MatTableDataSource初始化,但是为了使它正常工作是绝对必要的。

  • 为了使排序和分页正常工作,您必须给它们一个最小的延迟,因为初始化MatTableDataSource会在后台花费一些时间

  • 这意味着MatTableDataSource在分配排序和分页器时必须完全初始化,以使其正常工作。

    ngOnInit() {
      this.dataSource = new MatTableDataSource(users);
    
      setTimeout(function(){
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
      }, 1)
    }