Angular 11:如何在subscribe后使用方法存储的数据渲染图表?
Angular 11 异步数据加载后渲染图表的解决方案
你的问题核心是异步请求未完成就同步初始化了Chart,导致图表拿到的是空值。这里提供两种可行的解决方式:
方式一:用RxJS的forkJoin等待所有请求完成
forkJoin可以同时发起多个Observable请求,只有当所有请求都成功返回后才会触发回调,适合这种需要多份数据才能渲染的场景。
修改后的代码:
import { forkJoin } from 'rxjs'; // 别忘了导入forkJoin ... charts: any numberEditing: number = 0; // 初始化默认值 numberPublished: number = 0; // 初始化默认值 ... constructor( private measureService: MeasureService, ) { } ... ngOnInit() { // 合并两个请求 forkJoin([ this.measureService.getEditing(), this.measureService.getPublished() ]).subscribe(([editingData, publishedData]) => { this.numberEditing = editingData.length; this.numberPublished = publishedData.length; // 所有数据就绪后初始化图表 this.initChart(); }); } initChart() { this.chart = new Chart('canvas', { type: "doughnut", data: { labels: ["Test 1", "Test 2"], datasets: [ { data: [this.numberEditing, this.numberPublished], backgroundColor: ['rgba(255, 0, 0, 1)', 'rgba(13, 180, 185, 1)'] } ], }, }); }
方式二:数据更新后检查就绪状态,再初始化/更新图表
如果两个请求可能先后返回,也可以在每个数据赋值后检查是否两个数据都已获取到,再执行图表初始化或更新操作:
... charts: any numberEditing: number | undefined; numberPublished: number | undefined; ... ngOnInit() { this.getPublished(); this.getEdits(); } getPublishedNumber(numberPublished: number) { this.numberPublished = numberPublished; this.checkAndInitChart(); } getNumberEditing(numberEditing: number) { this.numberEditing = numberEditing; this.checkAndInitChart(); } checkAndInitChart() { // 确保两个数据都已赋值 if (this.numberEditing !== undefined && this.numberPublished !== undefined) { if (!this.chart) { // 初始化图表 this.chart = new Chart('canvas', { type: "doughnut", data: { labels: ["Test 1", "Test 2"], datasets: [ { data: [this.numberEditing, this.numberPublished], backgroundColor: ['rgba(255, 0, 0, 1)', 'rgba(13, 180, 185, 1)'] } ], }, }); } else { // 如果图表已存在,更新数据 this.chart.data.datasets[0].data = [this.numberEditing, this.numberPublished]; this.chart.update(); } } } getEdits() { this.measureService.getEditing().subscribe(data => this.getNumberEditing(data.length)) } getPublished() { this.measureService.getPublished().subscribe(data => this.getPublishedNumber(data.length)) }
注意事项
- 记得给
numberEditing和numberPublished初始化默认值或明确类型,避免undefined导致的问题。 - 如果图表可能需要后续更新数据(比如用户操作后重新加载),方式二更适合,因为可以复用
checkAndInitChart来更新图表数据并调用chart.update()。
内容的提问来源于stack exchange,提问作者Amanda
相关产品推荐
相关产品推荐

