在 Angular Material Table 中显示数据

Display Data in Angular Material Table

我正在为 Angular mat-table 库苦苦挣扎。我有一个带有 Node.js 后端和 Angular 前端的应用程序。节点应用程序在 JSON.

中提供来自 MySQL 数据库的数据

现在我想在 mat-table 中显示这些数据。我已经在控制台中记录了数据,这使我可以看到数据实际上已检索到,只是没有显示。

然而,HTML table 是空的:

这是我的 Angular 组件:

component.html

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8 demo-table">
  <ng-container matColumnDef="id">
    <th mat-header-cell *matHeaderCellDef>ID</th>
    <td mat-cell *matCellDef="let element">{{element.id}}</td>
  </ng-container>
  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef>Name</th>
    <td mat-cell *matCellDef="let element">{{element.name}}</td>
  </ng-container>
  <ng-container matColumnDef="pop">
    <th mat-header-cell *matHeaderCellDef>Population</th>
    <td mat-cell *matCellDef="let element">{{element.population}}</td>
  </ng-container>


  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr
      mat-row
      (click)="clickedRows.add(row)"
      [class.demo-row-is-clicked]="clickedRows.has(row)"
      *matRowDef="let row; columns: displayedColumns;"
  ></tr>
</table>

component.ts

import {Component, OnInit,ViewChild} from '@angular/core';
import { Player } from '../player';
import { PlayerService } from '../player.service';
import { MatTableDataSource } from '@angular/material/table';
import {MatPaginator} from '@angular/material/paginator';
import {MatSort, SortDirection} from '@angular/material/sort';

/**
 * @title Binding event handlers and properties to the table rows.
 */
@Component({
  selector: 'app-players',
  styleUrls: ['players.component.css'],
  templateUrl: 'players.component.html',
})
export class PlayersComponent implements OnInit {
  displayedColumns: string[] = ['id', 'name', 'pop'];
  dataSource = new MatTableDataSource<Player>();

  @ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator;
  @ViewChild(MatSort, { static: true }) sort!: MatSort;

  constructor(private playerService:PlayerService) { }

  ngOnInit(): void {
    this.getPlayers();
  }

  getPlayers() {
    this.playerService.getPlayers().subscribe(players => {
      console.log(players);
      this.dataSource.data = players;
      this.dataSource.paginator = this.paginator;
      this.dataSource.sort = this.sort;
    });
  }
  clickedRows = new Set<Player>();
}

player.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { Player } from './player';

@Injectable({
  providedIn: 'root'
})
export class PlayerService {

  constructor(private http: HttpClient) { }
  rootURL = '/api';
  getPlayers(): Observable<Player[]> {
    return this.http.get<Player[]>(this.rootURL+ '/players');
  }
}

对此有什么想法吗?

编辑: 它与数组如何从 API 返回有关吗?在 Node.js 中,它是用 sequelize 检索的,也许它是响应?

// Get all Players
exports.findAll = (req, res) => {
    Player.findAll().then((players) => {
    // Send all players as response
    res.status(200).json({
      status: true,
      data: players,
    });
  });
};

创建 MatTableDataSource 实例并分配给数据源。 试试这个选项

this.dataSource = new MatTableDataSource(players);
this.dataSource.sort = this.sort;

参考:

问题

根据截图和Node.js API返回的数据不是Player数组,而是一个具有statusdata属性的对象.

{
  "status": 200,
  "data": [...]
}

此行要求 HTTP GET 接收与您的数据冲突的 Player 数组。

this.http.get<Player[]>(this.rootURL+ '/players');

因此,它 returns 可以用空数组观察,而您的 <mat-table> 将不会显示数据。


解决方案

使用 map rxjs 运算符将数据转换为 Player 数组。

import { map } from 'rxjs';

getPlayers(): Observable<Player[]> {
  return this.http
    .get(this.rootURL+ '/players')
    .pipe(map((response: any) => response.data as Player[]));
}

Sample Solution on StackBlitz