You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中Http Get请求数据无法在mat-table正常显示的问题

问题解决步骤

核心问题分析

  1. Angular Material Table 必须接收数组类型的数据源,单个对象无法触发行渲染。
  2. 未正确使用MatTableDataSource,直接绑定原始数据变量导致分页、排序功能失效,且数据更新时无法触发表格刷新。
  3. 分页器和排序组件的初始化时机错误,@ViewChild获取的组件在ngOnInit阶段尚未完成初始化。

修复方案

1. 修正TypeScript组件代码

import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { DeviceMi } from '../models/DeviceMi';
import { AuthenticationService } from '../service/authentication.service';

@Component({
  selector: 'app-mi',
  templateUrl: './mi.component.html',
  styleUrls: ['./mi.component.css']
})
export class MiComponent implements OnInit, AfterViewInit {
  displayedColumns: string[] = ['fabrNumberModel', 'deviceNameModel', 'deviceStateModel', 'deviceTypeModel', 'deviceTemperatureModel', 'actions'];
  dataSource!: MatTableDataSource<DeviceMi>;

  @ViewChild('paginationMiDevicesListing') paginator!: MatPaginator;
  @ViewChild('sortDevicesListing') sort!: MatSort;

  constructor(
    private responseService: AuthenticationService,
  ) { }

  ngOnInit() {
    // 初始化空的数据源
    this.dataSource = new MatTableDataSource<DeviceMi>([]);
    this.displayMiDevices();
  }

  ngAfterViewInit() {
    // 视图初始化完成后再绑定分页器和排序组件
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }

  displayMiDevices() {
    const accessToken = localStorage.getItem('accessToken');
    console.log(accessToken);
    
    this.responseService.getV1Devices().subscribe(data => {
      console.log(data);
      // 确保数据源是数组:如果返回单个对象则包装为数组,否则直接使用
      const deviceData = Array.isArray(data) ? data : [data];
      // 更新数据源触发表格刷新
      this.dataSource.data = deviceData;
    });
  } 

  powerOnAction(row: DeviceMi) {
    // 实现你的设备开机逻辑
    console.log('触发开机操作:', row);
  }
}

2. 修正HTML模板代码

<div class="container mat-elevation-z8">
    <mat-table [dataSource]="dataSource" matSort>
    
      <!-- Mi Device Id Column -->
      <ng-container matColumnDef="fabrNumberModel">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Mi Device ID </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.fabrNumberModel}} </mat-cell>
      </ng-container>
    
      <!-- Device Name Column -->
      <ng-container matColumnDef="deviceNameModel">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Device Name </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.deviceNameModel}} </mat-cell>
      </ng-container>
    
      <!-- Device State Column -->
      <ng-container matColumnDef="deviceStateModel">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Device State </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.deviceStateModel}} </mat-cell>
      </ng-container>
    
      <!-- Device Type Column -->
      <ng-container matColumnDef="deviceTypeModel">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Device Type </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.deviceTypeModel}} </mat-cell>
      </ng-container>
    
      <!-- Device Temperature Column -->
      <ng-container matColumnDef="deviceTemperatureModel">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Device Temperature </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.deviceTemperatureModel}} </mat-cell>
      </ng-container>
    
      <!-- Button Column -->
      <ng-container matColumnDef="actions">
        <th class="actionName" mat-header-cell *matHeaderCellDef><mat-icon>power_settings_new</mat-icon></th>
        <mat-cell *matCellDef="let row">
            <mat-slide-toggle class="powerOnButton" (click)="powerOnAction(row)"></mat-slide-toggle>
            <mat-icon>power_on</mat-icon>
        </mat-cell>
      </ng-container>
    
      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
    </mat-table>
    
    <mat-paginator #paginationMiDevicesListing [pageSizeOptions]="[5, 10, 20]"
                    showFirstLastButtons 
                    aria-label="选择设备列表页码">
    </mat-paginator>
  </div>

关键修复点说明

  1. 统一使用MatTableDataSource:模板绑定[dataSource]="dataSource",确保表格能正确响应数据更新,同时支持分页、排序功能。
  2. 数据源数组化处理:通过Array.isArray()自动适配API返回格式,单个对象包装为数组后可正常渲染一行数据。
  3. 修正生命周期钩子:将分页器和排序组件的绑定移至ngAfterViewInit,避免视图元素未初始化导致的绑定失效。
  4. 移除硬编码分页长度:MatTableDataSource会自动根据数据长度计算分页总数,无需手动设置[length]="50"。

内容的提问来源于stack exchange,提问作者Bilel-NEJI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 22:45:39