Angular Material - mat-table 不渲染来自 rest api 的数据

Posted

技术标签:

【中文标题】Angular Material - mat-table 不渲染来自 rest api 的数据【英文标题】:Angular Material - mat-table not rendering data from rest api 【发布时间】:2019-07-01 17:00:37 【问题描述】:

我一直在尝试从 Angular Material 实现 this 表格示例,但没有运气

我不明白我做错了什么,我的 REST 端点提供的数据在控制台输出上清晰可见。

我的怀疑是,当表格呈现时,数据可能还没有完全加载。任何帮助表示赞赏,谢谢!

lap.component.ts

import Component, OnInit, ViewChild from '@angular/core';
import MatPaginator, MatSort, MatTableDataSource from '@angular/material';
import Router from '@angular/router';
import LapService from '../shared/services/lap.service';
import Lap from '../shared/model/lap.model';

@Component(
  selector: 'app-lap',
  templateUrl: './lap.component.html',
  styleUrls: ['./lap.component.css']
)
export class LapComponent implements OnInit 

  displayedColumns = ['id', 'year', 'lap', 'shortcut flag', 'start place', 'destination place', 'length', 'height difference'];
  dataSource: MatTableDataSource<Lap>;

  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;


  constructor(public rest: LapService, private router: Router) 
  

  ngOnInit() 
    this.dataSource = new MatTableDataSource(this.getLaps());
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  


  applyFilter(filterValue: string) 
    this.dataSource.filter = filterValue.trim().toLowerCase();

    if (this.dataSource.paginator) 
      this.dataSource.paginator.firstPage();
    
  

  getLaps() 
    this.rest.getLaps().subscribe((data: ) => 
      console.log(data);
      console.log('Laps');
      return data;
    );
  

lap.component.html

<mat-form-field>
  <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>

<div class="mat-elevation-z8">
  <table mat-table [dataSource]="dataSource" matSort>

    <!-- ID Column -->
    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> ID </th>
      <td mat-cell *matCellDef="let row "> row.id </td>
    </ng-container>

    <!-- Year Column -->
    <ng-container matColumnDef="year">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Year </th>
      <td mat-cell *matCellDef="let row"> row.year </td>
    </ng-container>

    <!-- Lap Column -->
    <ng-container matColumnDef="lap">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Lap </th>
      <td mat-cell *matCellDef="let row"> row.lap </td>
    </ng-container>

    <!-- Shortcut Column -->
    <ng-container matColumnDef="shortcut flag">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Shortcut Flag </th>
      <td mat-cell *matCellDef="let row" [style.color]="row.color"> row.shortcut_flag </td>
    </ng-container>

    <!-- Start Column -->
    <ng-container matColumnDef="start place">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Start Place </th>
      <td mat-cell *matCellDef="let row"> row.start_place </td>
    </ng-container>

    <!-- Destination Column -->
    <ng-container matColumnDef="destination place">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Destination Place </th>
      <td mat-cell *matCellDef="let row"> row.destination_place </td>
    </ng-container>

    <!-- Length Column -->
    <ng-container matColumnDef="length">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Length </th>
      <td mat-cell *matCellDef="let row"> row.length </td>
    </ng-container>

    <!-- Height Column -->
    <ng-container matColumnDef="height difference">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Height Difference </th>
      <td mat-cell *matCellDef="let row"> row.height_difference </td>
    </ng-container>

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

  <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
</div>

lap.service.ts

import Injectable from '@angular/core';
import HttpClient, HttpHeaders from '@angular/common/http';
import Observable from 'rxjs';
import map from 'rxjs/operators';

@Injectable(
  providedIn: 'root'
)
export class LapService 

  private lapUrl = 'http://localhost:8080/api/lap';
  private httpOptions = 
    headers: new HttpHeaders(
      'Content-Type': 'application/json'
    )
  ;

  constructor(private http: HttpClient)  

  getLaps(): Observable<any> 
    return this.http.get(this.lapUrl, this.httpOptions).pipe(
      map(this.extractData));
  

  private extractData(res: Response) 
    return res || ; // If 'res' is null, it returns empty object
  


【问题讨论】:

你能告诉我们控制台错误吗? 【参考方案1】:

您需要创建new MatTableDataSource(),然后在接收数据时将该数据传递给dataSource.data 数组。

 ngOnInit() 
   // this.dataSource = new MatTableDataSource(this.getLaps());
    this.dataSource = new MatTableDataSource(); // create new object
    this.getLaps(); // forgeted this line
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
 

   getLaps() 
     this.rest.getLaps().subscribe((data: ) => 
       console.log(data);
       console.log('Laps');
       this.dataSource.data = data; // on data receive populate dataSource.data array
       return data;
    );
  

【讨论】:

此外,我不得不在 ngOnInit() 方法中调用 getLaps() 方法,这对我有用,非常感谢!【参考方案2】:

你忘了在ngOnInit上添加这一行:

 this.getLaps(); 

【讨论】:

以上是关于Angular Material - mat-table 不渲染来自 rest api 的数据的主要内容,如果未能解决你的问题,请参考以下文章

AngularCLI 和 Angular Material(原理图)错误:无法解析集合“@angular/material”

无法导入“@angular/material”模块

Angular2 Material:Angular 材质输入的自定义验证

Angular Material 设计

如何有效地使用 Angular Material 自定义调色板颜色 Angular Material

Angular 2 Material - 如何居中进度微调器