Angular5/TypeScript无法设置变量:组件初始化检测服务器可达性问题
解决Angular组件回调中无法访问组件变量的问题
你碰到的核心问题是普通函数回调里的this指向不对——在img.onload和img.onerror的function里,this指向的是创建的<img>元素本身,而不是你的AppComponent实例,所以没法直接修改组件的dataServerOffline变量。
下面给你三种常用的解决办法,按推荐程度排序:
1. 使用箭头函数(最推荐,Angular开发中的常规操作)
箭头函数不会绑定自己的this,它会自动捕获当前上下文的this(也就是你的组件实例)。直接把回调改成箭头函数就行:
export class AppComponent implements OnInit { dataServerOffline: boolean = true; constructor() { } ngOnInit() { const img = document.body.appendChild(document.createElement("img")); img.style.display = "none"; img.src = "http://myUrl.com/online.jpeg"; // 改用箭头函数 img.onload = () => { this.dataServerOffline = false; // 现在this指向组件实例了 }; img.onerror = () => { this.dataServerOffline = true; // 这里也可以正常访问 // 其他错误处理逻辑 }; } }
2. 提前保存组件的this到变量
如果习惯用普通函数,可以在回调外面先把组件的this存到一个变量(比如that、self),然后在回调里用这个变量访问组件:
ngOnInit() { const that = this; // 保存组件实例的引用 const img = document.body.appendChild(document.createElement("img")); img.style.display = "none"; img.src = "http://myUrl.com/online.jpeg"; img.onload = function () { that.dataServerOffline = false; // 用that代替this访问组件变量 }; img.onerror = function () { that.dataServerOffline = true; // 其他错误处理逻辑 }; }
3. 用bind()绑定this到组件实例
通过bind()方法,把普通函数的this强制绑定为组件实例:
ngOnInit() { const img = document.body.appendChild(document.createElement("img")); img.style.display = "none"; img.src = "http://myUrl.com/online.jpeg"; img.onload = function () { this.dataServerOffline = false; }.bind(this); // 绑定this为组件实例 img.onerror = function () { this.dataServerOffline = true; // 其他错误处理逻辑 }.bind(this); }
额外建议:用Angular的HttpClient检测服务器可达性
其实用<img>标签检测服务器状态可能会有缓存问题,而且不够直观。Angular自带的HttpClient是更合适的方案:
// 首先在模块中导入HttpClientModule,然后在组件构造函数注入HttpClient import { HttpClient } from '@angular/common/http'; export class AppComponent implements OnInit { dataServerOffline: boolean = true; constructor(private http: HttpClient) { } ngOnInit() { // 发送HEAD请求更轻量,不需要下载整个图片 this.http.head("http://myUrl.com/online.jpeg") .subscribe({ next: () => this.dataServerOffline = false, error: () => this.dataServerOffline = true }); } }
内容的提问来源于stack exchange,提问作者user7878464
相关产品推荐
相关产品推荐

