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

Angular数据网格无法从WebAPI加载数据问题求助

Angular + Sky AG Grid 数据加载异常问题

我是Angular新手,正在实现一个从WebAPI拉取数据的基础数据网格。API返回的数据能在控制台正常打印,但把它作为rowData传入网格时完全不显示;但如果把相同数据定义成常量数组,网格却能正常渲染。


相关代码

component.ts

import { ChangeDetectionStrategy, Component, OnInit, OnDestroy } from '@angular/core';
import { SkyAgGridService, SkyCellType } from '@skyux/ag-grid';
import { Student } from 'src/app/models/student.model';
import { StudentsService } from 'src/app/services/students.service';
import { BehaviorSubject, Subscription } from 'rxjs';

import {
  ColDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ValueFormatterParams,
} from 'ag-grid-community';

import { SKY_AG_GRID_DEMO_DATA } from './basic-data-grid-docs-demo-data';

@Component({
  selector: 'app-basic-data-grid-docs-demo',
  templateUrl: './basic-data-grid-docs-demo.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SkyBasicDataGridDemoComponent implements OnInit{

  students: Student[] = [];
  
  public columnDefs: ColDef[] = [
    {
      field: 'FirstMidName',
      headerName: 'Name',
    },
    {
      field: 'LastName',
      headerName: 'Last Name',
    },
    {
      field: 'Gender',
      headerName: 'Gender'
    },
    {
      field: 'EnrollmentDate',
      headerName: 'Enrollment date',
      type: SkyCellType.Date,
    },
    
  ];

  public gridApi: GridApi | undefined;
  public gridData: any[] = SKY_AG_GRID_DEMO_DATA; // 用常量数据时网格正常显示
  public gridOptions: GridOptions;
  public searchText = '';
  public getStudentsSubscription: Subscription | undefined;
  

  ngOnInit(): void {
    this.studentsService.getAllStudents()
    .subscribe({
      next: (students) => {
        this.students= students;
        console.log("this is students", students);
        console.log(this.gridData);
      },
      error: (response) => {
        console.log(response);
      }
    });
  }

  constructor(private agGridService: SkyAgGridService, private studentsService: StudentsService) {
      this.gridOptions = {
      columnDefs: this.columnDefs,
     onGridReady: (gridReadyEvent): void => this.onGridReady(gridReadyEvent),
     rowSelection: 'single',
    };
    this.gridOptions = this.agGridService.getGridOptions({
      gridOptions: this.gridOptions,
    });
  }

  public onGridReady(gridReadyEvent: GridReadyEvent): void {
    this.gridApi = gridReadyEvent.api;
    this.gridApi.sizeColumnsToFit();
  }
}

component.html

<div>
    <sky-ag-grid-wrapper>
      <ag-grid-angular [gridOptions]="gridOptions" [rowData]="students">
      </ag-grid-angular>
    </sky-ag-grid-wrapper>
</div>

API服务代码

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
import { Student } from '../models/student.model';

@Injectable({
  providedIn: 'root'
})
export class StudentsService {
  baseApiUrl: string = environment.baseApiUrl;

  constructor(private http: HttpClient) { }

  getAllStudents(): Observable<Student[]>{
      return this.http.get<Student[]>(this.baseApiUrl + 'api/student');
  }
}

模型定义

export interface Student{
    ID: number;
    FirstMidName: string;
    LastName: string;
    Gender: string;
    EnrollmentDate: Date;
}

可正常显示的常量数据

export const SKY_AG_GRID_DEMO_DATA = [
    {ID:2,
    FirstMidName:"John333",
    LastName:"Doe222",
    Gender:"Male",
    EnrollmentDate:"2022-12-26T00:00:00"},
    {ID:3,
    FirstMidName :"John2",
    LastName:"Doe2",
    Gender:"Male",
    EnrollmentDate:"2022-12-21T00:00:00"},
    {ID:4,
    FirstMidName:"Lois",
    LastName:"Lane",
    Gender:"Female",
    EnrollmentDate:"2023-01-12T00:00:00"}
  ];

问题原因

组件启用了ChangeDetectionStrategy.OnPush变更检测策略,这种模式下Angular只会在输入属性引用变化、组件触发事件或手动触发变更检测时更新视图。当API返回数据后直接赋值给students数组时,虽然数组内容变了,但组件没有检测到变更,导致AG Grid没有收到数据更新。


解决方案

方案1:手动触发变更检测

在组件中注入ChangeDetectorRef,在获取到数据后手动触发变更检测:

  1. 导入ChangeDetectorRef:
import { ChangeDetectorRef } from '@angular/core';
  1. 构造函数注入:
constructor(
  private agGridService: SkyAgGridService, 
  private studentsService: StudentsService,
  private cdr: ChangeDetectorRef // 新增
) { ... }
  1. 在subscribe的回调中触发检测:
next: (students) => {
  this.students = students;
  this.cdr.detectChanges(); // 手动触发变更检测
}

方案2:直接用AG Grid API设置行数据

通过gridApi直接设置行数据,跳过Angular变更检测的依赖:

修改ngOnInit中的subscribe回调:

next: (students) => {
  this.students = students;
  if (this.gridApi) {
    this.gridApi.setRowData(students); // 直接给网格设置数据
  }
}

方案3:用BehaviorSubject+Async管道管理数据

用BehaviorSubject存储数据,模板中用async管道订阅,这种方式能自动触发OnPush模式下的变更检测:

  1. 修改组件中的students定义:
import { BehaviorSubject } from 'rxjs';
// 替换原来的students数组
students$ = new BehaviorSubject<Student[]>([]);
  1. 更新subscribe回调:
next: (students) => {
  this.students$.next(students); // 发送新数据到Subject
}
  1. 修改模板中的rowData绑定:
<ag-grid-angular [gridOptions]="gridOptions" [rowData]="students$ | async">

内容的提问来源于stack exchange,提问作者Shivansh Trigunait

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 00:12:23