Angular中获取异步数据后重新渲染Apex Chart的方案
解决Angular中ApexCharts数据加载前渲染为空的问题
有两种常用方案可以解决这个问题,分别是等待数据加载完成后再渲染图表和数据加载完成后更新图表配置触发重渲染,下面是具体实现:
方案一:等待数据加载完成后再渲染图表
通过*ngIf指令控制图表的渲染时机,确保只有当数据完全加载并处理完成后,才渲染ApexCharts组件。
修改代码:
- 组件类(component.ts):
import { Component, OnInit } from '@angular/core'; import { DataService } from './data.service'; @Component({ selector: 'app-chart', templateUrl: './chart.component.html', styleUrls: ['./chart.component.css'] }) export class ChartComponent implements OnInit { chartOptions: any = { series: [], chart: { type: 'line', // 根据你的需求调整图表类型 height: 350 }, xaxis: { categories: [] }, dataLabels: { enabled: false } }; dataLoaded = false; // 标记数据是否加载完成 constructor(private dataService: DataService) {} ngOnInit(): void { this.dataService.getDayData().subscribe((data) => { const xTime: string[] = []; const yValue: number[] = []; for (let dataelt of data) { xTime.push(new Date(dataelt.DateTime).toISOString().slice(11, 16)); yValue.push(parseFloat(dataelt.Value)); } // 更新图表配置 this.chartOptions.series = [{ name: 'Active Power L1', data: yValue }]; this.chartOptions.xaxis.categories = xTime; this.dataLoaded = true; // 标记数据加载完成 }); } }
- 模板文件(component.html):
<div id="chart"> <!-- 只有dataLoaded为true时才渲染图表 --> <apx-chart *ngIf="dataLoaded" [series]="chartOptions.series" [chart]="chartOptions.chart" [xaxis]="chartOptions.xaxis" [dataLabels]="chartOptions.dataLabels" ></apx-chart> </div>
- 服务类(data.service.ts):移除服务中存储数据的变量,只保留数据获取逻辑(服务不应存储视图状态):
import { Injectable } from "@angular/core"; import { HttpClient } from "@angular/common/http"; import { Observable } from "rxjs"; @Injectable({ providedIn: "root", }) export class DataService { constructor(private http: HttpClient) {} getDayData(): Observable<any> { let url = "http://localhost:4997/activepowerL1?DateTime=1620352800000"; return this.http.get(url); } }
方案二:数据加载完成后更新图表配置触发重渲染
ApexCharts的Angular组件是响应式的,当绑定的chartOptions对象发生变化时,组件会自动重新渲染。我们只需要在数据加载完成后更新chartOptions的相关属性即可。
修改代码(基于方案一的组件类调整):
不需要dataLoaded标志位,直接在数据处理完成后更新chartOptions:
// component.ts 中的ngOnInit部分 ngOnInit(): void { this.dataService.getDayData().subscribe((data) => { const xTime: string[] = []; const yValue: number[] = []; for (let dataelt of data) { xTime.push(new Date(dataelt.DateTime).toISOString().slice(11, 16)); yValue.push(parseFloat(dataelt.Value)); } // 注意:这里要重新赋值chartOptions对象,而不是只修改内部属性 // 这样才能触发Angular的变更检测,让图表重渲染 this.chartOptions = { ...this.chartOptions, series: [{ name: 'Active Power L1', data: yValue }], xaxis: { ...this.chartOptions.xaxis, categories: xTime } }; }); }
对应的模板文件不需要*ngIf,直接保留原有的apx-chart标签即可。
注意事项
- 不要在服务中存储视图相关的数据(比如
datax、xTime),这类数据应该由组件自己管理,避免状态混乱。 - 如果使用方案二,必须重新赋值
chartOptions对象(而不是仅修改内部属性),否则Angular的变更检测可能无法识别到变化,导致图表不更新。
内容的提问来源于stack exchange,提问作者FloHaschke
相关产品推荐
相关产品推荐

