Angular4指令中创建HTMLImageElement时无法访问this对象的问题
解决Angular指令中Image.onload回调无法访问类实例
this的问题 你碰到的是JavaScript里非常常见的上下文绑定问题:当你用普通function定义onload回调时,回调内部的this指向的是触发事件的Image实例,而不是你的Angular指令类实例,所以自然访问不到renderer、el这些类属性。
下面给你三种靠谱的解决方案,按推荐程度排序:
1. 使用箭头函数(最推荐)
ES6的箭头函数不会创建自己的this上下文,它会继承外层作用域的this——也就是你的指令类实例。修改后的代码如下:
ngAfterViewInit() { this.renderer.setAttribute(this.el.nativeElement, "src", this.onePxlImgPlaceHolder); // 创建HTML图片元素以在后台加载图片 this.dynamicImg = new Image(); // 注册图片加载完成时调用的函数(箭头函数绑定类的this) this.dynamicImg.onload = () => { this.renderer.setAttribute(this.el.nativeElement, "src", this.dynamicImg.src); }; this.dynamicImg.src = this.originalImgSrc; }
这种写法简洁直观,也是Angular项目中处理回调上下文的标准做法。
2. 提前保存类实例的this到变量
如果是兼容ES5的场景,可以在回调外部把类的this存到一个变量(比如self、that),然后在回调里用这个变量访问类属性:
ngAfterViewInit() { this.renderer.setAttribute(this.el.nativeElement, "src", this.onePxlImgPlaceHolder); this.dynamicImg = new Image(); // 保存类实例的this到变量 const self = this; this.dynamicImg.onload = function () { self.renderer.setAttribute(self.el.nativeElement, "src", self.dynamicImg.src); }; this.dynamicImg.src = this.originalImgSrc; }
3. 使用bind()绑定上下文
通过Function.prototype.bind()方法,把回调函数的this强制绑定为类实例:
ngAfterViewInit() { this.renderer.setAttribute(this.el.nativeElement, "src", this.onePxlImgPlaceHolder); this.dynamicImg = new Image(); this.dynamicImg.onload = function () { this.renderer.setAttribute(this.el.nativeElement, "src", this.dynamicImg.src); }.bind(this); // 绑定类实例的this到回调 this.dynamicImg.src = this.originalImgSrc; }
以上三种方法都能解决你的问题,优先选箭头函数就好,代码更干净易读。
内容的提问来源于stack exchange,提问作者Code Guru
相关产品推荐
相关产品推荐

