Angular引入steelseries报Cannot read 'theme' of undefined错误求助
错误原因
报错本质是ProjectService中的projectData.hmi.layout在读取theme属性时还未完成赋值,属于数据加载时序问题,和你引入steelseries库没有直接关联,同时你的compass组件写法也存在不符合Angular规范的问题,以下是修复步骤:
修复步骤
1. 给getLayoutTheme方法加空值防护
你当前使用的TypeScript 2.7.2版本不支持可选链语法,需要逐层判空避免读取undefined的属性:
// project.service.ts getLayoutTheme() { // 逐层判断数据是否存在 if (this.projectData && this.projectData.hmi && this.projectData.hmi.layout) { return this.projectData.hmi.layout.theme; } // 数据未加载完成时返回默认主题,可替换为你项目的默认主题常量 return 'default'; }
2. 修正Header组件的主题加载时序
不要在构造函数中调用getLayoutTheme,此时项目数据还未完成加载,将构造函数中的主题设置逻辑移到onLoadHmi的订阅回调中:
// header.component.ts 构造函数删除这行 // this.themeService.setTheme(this.projectService.getLayoutTheme()); // 修改ngAfterViewInit中的订阅逻辑 ngAfterViewInit() { this.subscriptionLoad = this.projectService.onLoadHmi.subscribe(load => { let theme = this.projectService.getLayoutTheme(); this.darkTheme = (theme !== ThemeService.ThemeType.Default); this.themeService.setTheme(theme); }, error => { console.log('Error loadHMI'); }); }
同时确保ProjectService的notifyToLoadHmi方法是在projectData完整赋值之后才触发的,避免提前发送加载完成事件。
3. 修正html-compass组件的错误写法
组件模板调整
Angular组件的模板不需要全局html、body标签,也不要直接在模板中引入本地node_modules的脚本,删除冗余内容:
<!-- html-compass.component.html --> <canvas id="myCanvas"></canvas>
脚本引入配置
打开项目根目录的angular.json,找到projects -> 你的项目名 -> architect -> build -> options -> scripts配置项,添加steelseries的脚本路径:
"scripts": [ "node_modules/steelseries/dist/steelseries.min.js" ]
组件逻辑调整
不要给div绑定无用的ngModelChange事件,Compass初始化要等canvas元素渲染完成后执行:
// html-compass.component.ts import { Component, AfterViewInit } from '@angular/core'; import { Compass } from "steelseries"; @Component({ selector: 'app-html-compass', templateUrl: './html-compass.component.html', styleUrls: ['./html-compass.component.css'] }) export class HtmlCompassComponent implements AfterViewInit { static TypeTag = 'svg-ext-html_compass'; static LabelTag = 'HtmlCompass'; static prefixB = 'B-HXB_'; static prefixRect = 'svg_'; constructor() { } ngAfterViewInit() { const canvas = document.querySelector("#myCanvas"); if (canvas) { const compass = new Compass(canvas, {size: 200}); } } }
内容的提问来源于stack exchange,提问作者Ionut
相关产品推荐
相关产品推荐

