Angular组件传值问题:RSI数据传递至图表组件触发map未定义错误
解决Angular组件初始化时读取RSI数据报
Cannot read property 'map' of undefined的问题 这问题我之前做指标可视化的时候也踩过坑,本质就是组件初始化时机和数据生成时机不匹配导致的:
问题根源拆解
你现在是把rsi_result作为常量导出,而setRsi()是点击按钮后才触发生成数据的。但NgxChartsComponent在页面加载时就会执行初始化逻辑(比如ngOnInit),这时候rsi_result还没被赋值,自然是undefined,调用map就会报错。虽然之后点击按钮能在控制台打印出数据,但组件的初始化逻辑早就跑完了,不会自动重新执行。
靠谱的解决方案
方案1:用共享服务实现数据通信(最推荐,适合跨组件/对话框场景)
通过Angular服务的Subject来传递数据,让图表组件能实时监听数据变化:
- 创建共享服务
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class IndicatorService { // 用BehaviorSubject可以给新订阅者发送最近一次的数据,初始值设为空数组避免undefined private rsiResult$ = new BehaviorSubject<any[]>([]); // 对外暴露可观察对象,防止外部直接修改数据源 public rsiResultObservable = this.rsiResult$.asObservable(); // 更新RSI数据的方法 updateRsiResult(data: any[]) { this.rsiResult$.next(data); } }
- 在FlowComponent中发送数据
import { IndicatorService } from './indicator.service'; export class FlowComponent { constructor(private indicatorService: IndicatorService) {} setRsi() { // 你的RSI生成逻辑 const rsi_result = [...]; // 生成的结果数组 console.log(rsi_result); // 把数据发送到共享服务 this.indicatorService.updateRsiResult(rsi_result); // 打开对话框 this.doOutput(); } doOutput() { // 对话框打开逻辑 } }
- 在NgxChartsComponent中订阅数据并处理
import { Component, OnInit, OnDestroy } from '@angular/core'; import { IndicatorService } from './indicator.service'; import { takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; export class NgxChartsComponent implements OnInit, OnDestroy { private destroy$ = new Subject<void>(); chartData: any[] = []; constructor(private indicatorService: IndicatorService) {} ngOnInit() { // 订阅RSI数据的变化 this.indicatorService.rsiResultObservable .pipe(takeUntil(this.destroy$)) // 防止内存泄漏 .subscribe(rsiData => { if (rsiData && rsiData.length > 0) { // 这里执行你的map转换逻辑 this.chartData = rsiData.map(item => ({ name: item.timePoint, // 替换成你的字段 value: item.rsiValue // 替换成你的字段 })); } else { this.chartData = []; // 空数据时重置图表 } }); } ngOnDestroy() { // 销毁订阅 this.destroy$.next(); this.destroy$.complete(); } }
方案2:父子组件输入输出(适合NgxCharts是FlowComponent子组件的场景)
如果图表组件是FlowComponent的子组件,直接用@Input和ngOnChanges监听数据变化:
- FlowComponent中定义数据并传递
export class FlowComponent { rsiResult: any[] = []; setRsi() { this.rsiResult = [...]; // 生成RSI数据 this.doOutput(); } doOutput() { // 对话框逻辑 } }
模板中传递数据:
<app-ngx-charts [rsiResult]="rsiResult"></app-ngx-charts>
- NgxChartsComponent中监听输入变化
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; export class NgxChartsComponent implements OnChanges { @Input() rsiResult: any[] = []; chartData: any[] = []; ngOnChanges(changes: SimpleChanges) { // 监听rsiResult的变化 if (changes.rsiResult && changes.rsiResult.currentValue) { const newData = changes.rsiResult.currentValue; this.chartData = newData.map(item => ({ name: item.date, value: item.rsi })); } } }
关键注意点
- 永远要在
map之前判断数据是否存在(比如rsiData && rsiData.length > 0),避免空指针; - 用
takeUntil销毁订阅防止内存泄漏,尤其是对话框组件; - 如果是弹窗里的图表,确保弹窗打开时数据已经准备好,或者在弹窗组件里订阅服务数据。
内容的提问来源于stack exchange,提问作者lovecode
相关产品推荐
相关产品推荐

