Angular 2中http.get获取数据时subscribe外变量undefined问题求助
解决Angular中HTTP请求异步导致图表初始化失败的问题
这是个很常见的异步操作时序问题,我来帮你搞定它!
问题根源
HTTP请求是异步的,当你在ngOnInit里调用getData()后,代码会立刻继续执行创建图表的逻辑,但这时候this.mock还没被赋值——因为http.get的回调函数(也就是subscribe里的代码)要等服务器返回数据后才会执行。而之前用of(MOCK)的时候,数据是同步发射的,subscribe的回调会立即执行,所以this.mock马上就有值,图表能正常渲染。
解决方案
把图表初始化的逻辑移到subscribe的回调内部,或者在回调里调用专门的图表创建方法,确保只有当数据成功返回后,才去初始化图表。
修改你的VizComponent代码如下:
import { Component, OnInit } from '@angular/core'; import { Mock } from './mock'; import { MockService } from '../mock.service'; import { Chart } from 'chart.js'; import 'chart.piecelabel.js'; @Component({ selector: 'app-viz', templateUrl: './viz.component.html', styleUrls: ['./viz.component.scss'] }) export class VizComponent implements OnInit { mock:Mock; options = { responsive: true, tooltips: { enabled: false }, legend: { display: false }, pieceLabel:{ render: 'percentage', // 修正原代码拼写错误:percetage → percentage precision: 0, showZero: true, fontSize: 12, fontColor: ['green', 'blue'], fontStyle: 'normal', fontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", textShadow: true, shadowBlur: 10, shadowOffsetX: -5, shadowOffsetY: 5, shadowColor: 'rgba(255,0,0,0.75)', arc: false, position: 'outside' } } constructor(private mockService: MockService) { } ngOnInit() { this.getData(); } getData(): void { this.mockService.getMockData() .subscribe(mock_data => { this.mock = mock_data; // 数据获取完成后再创建图表 this.initializeChart(); }); } // 单独封装图表初始化方法 initializeChart(): void { const ctx = "myChart"; new Chart(ctx, { type: this.mock.type, data: this.mock.data, options: this.options }); } }
额外提示
- 我顺便修正了你
pieceLabel里render属性的拼写错误,避免图表渲染异常。 - 如果你的模板里也用到了
mock的数据,建议在模板里添加*ngIf="mock"来防止未定义错误,比如:
<canvas *ngIf="mock" id="myChart"></canvas>
这样调整后,就能和之前用of算子时一样正常显示图表啦!
内容的提问来源于stack exchange,提问作者Sourav Ranjan Panda
相关产品推荐
相关产品推荐

