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

我正在尝试使用angular material创建一个表 . 我面临的问题是,在启动时表中没有显示任何数据 . 但是分页已经更新了数据大小 . 无法在组件加载后立即了解如何使数据可用 .

正如您在右侧所看到的,它显示了总共52条记录 .
enter image description here

只要我点击一些表格 Headers 进行排序,或者如果我点击下一个分页,行就会填充数据 .

非常感谢建议纠正这个问题 .

谢谢

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)

3 years ago

加载数据时,您不会向表中发送任何内容 .

问题出在这里 .

observableOf(this.data)

这些数据将在稍后加载 .

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

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

我会使用 combineLatest() 而不是 merge ,因为当任何输入的observable发出一个值时它会发出 .

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
});