使用Angular材质表加载零部件时无法显示数据

时间:2018-09-15 13:54:50

标签: angular typescript angular-material

我正在尝试使用angular material制作表格。我面临的问题是,表的开头没有显示任何数据。但是分页已更新了数据大小的数量。无法理解如何在组件加载后立即使数据可用。

如右图所示,它显示了52条记录。 enter image description here

当我单击某个表标题进行排序时,或者如果单击分页的下一个,则行将填充数据。

非常感谢您提出纠正建议。

谢谢

HTML文件

<div class="mat-elevation-z8">
  <table mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">
    <!-- Id Column -->
    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>Id</th>
      <td mat-cell *matCellDef="let row">{{row.snipsOutput.id}}</td>
    </ng-container>

    <!-- Name Column -->
    <ng-container matColumnDef="input">
      <th mat-header-cell *matHeaderCellDef mat-header>User Query</th>
      <td mat-cell *matCellDef="let row">{{row.snipsOutput.input}}</td>
    </ng-container>

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

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

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

NluDataTableComponent.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator, MatSort } from '@angular/material';
import { NluDataTableDataSource } from './nlu-data-table-datasource';
import { PfivaDataService } from '../services/pfiva-data.service';

@Component({
  selector: 'app-nlu-data-table',
  templateUrl: './nlu-data-table.component.html',
  styleUrls: ['./nlu-data-table.component.css']
})
export class NluDataTableComponent implements OnInit {
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;
  dataSource: NluDataTableDataSource;

  /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
  displayedColumns = ['id', 'input', 'hotword', 'intent', 'timestamp', 'feedbackQuery', 'feedbackUserResponse', 'feedbackTimestamp'];

  constructor(private pfivaDataService: PfivaDataService) {

  }

  ngOnInit() {
    this.dataSource = new NluDataTableDataSource(this.paginator, this.sort, this.pfivaDataService);
  }
}

NluDataTableDataSource.ts

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';
import { NLUData } from '../data-model/NLUData';
import { PfivaDataService } from '../services/pfiva-data.service';

/**
 * Data source for the NluDataTable view. This class should
 * encapsulate all logic for fetching and manipulating the displayed data
 * (including sorting, pagination, and filtering).
 */
export class NluDataTableDataSource extends DataSource<NLUData> {
  //data: NluDataTableItem[] = EXAMPLE_DATA;
  data: NLUData[] = [];

  constructor(private paginator: MatPaginator, 
    private sort: MatSort, private pfivaDataService: PfivaDataService) {
      super();
      this.fetchNLUData();
  }

  /**
   * Connect this data source to the table. The table will only update when
   * the returned stream emits new items.
   * @returns A stream of the items to be rendered.
   */
  connect(): Observable<NLUData[]> {
    // Combine everything that affects the rendered data into one update
    // stream for the data-table to consume.
    const dataMutations = [
      observableOf(this.data),
      this.paginator.page,
      this.sort.sortChange
    ];

    // Set the paginators length
    this.paginator.length = this.data.length;

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

  /**
   *  Called when the table is being destroyed. Use this function, to clean up
   * any open connections or free any held resources that were set up during connect.
   */
  disconnect() {}

  private fetchNLUData() {
    this.pfivaDataService.getNLUData()
    .subscribe(
      (nluData: NLUData[]) => this.data = nluData,
      (error) => console.log(error)
    );
  }

  /**
   * Paginate the data (client-side). If you're using server-side pagination,
   * this would be replaced by requesting the appropriate data from the server.
   */
  private getPagedData(data: NLUData[]) {
    const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
    return data.splice(startIndex, this.paginator.pageSize);
  }

  /**
   * Sort the data (client-side). If you're using server-side sorting,
   * this would be replaced by requesting the appropriate data from the server.
   */
  private getSortedData(data: NLUData[]) {
    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 'id': return compare(+a.snipsOutput.id, +b.snipsOutput.id, isAsc);
        default: return 0;
      }
    });
  }
}

/** Simple sort comparator for example ID/Name columns (for client-side sorting). */
function compare(a, b, isAsc) {
  return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
}

1 个答案:

答案 0 :(得分:1)

加载数据时,您不会向表发出任何东西。

问题在这里。

observableOf(this.data)

稍后将在此加载数据。

this.pfivaDataService.getNLUData()
.subscribe(
  (nluData: NLUData[]) => this.data = nluData,
  (error) => console.log(error)
);

connect(): Observable<NLUData[]>函数需要在数据更改时发出数据。由于您首先使用分页并对数据进行排序,因此当这些值更改时,它也需要发出。

我将使用combineLatest()而不是merge,因为它将在任何输入可观察对象发出值时发出。

return combineLatest(
     this.pfivaDataService.getNLUData(),
     this.paginator.page,
     this.sort.sortChange
).pipe(map(latest) => {
        // latest is an array of 3 in the order above

        // do data processing here
});