Angular 1.5+TypeScript项目addEventListener触发时函数调用报错排查
问题分析与解决方案
这个问题我太熟悉了!核心原因是事件回调函数里的this指向发生了变化,导致你无法访问组件实例上的方法。
为什么初始化正常,滚动时出错?
- 在
$onInit钩子的直接代码里,this指向的是你的组件实例(CustomerActivitiesComponent),所以调用this.scroll()和this.doSomething()都没问题。 - 但在
addEventListener的普通函数回调里,this默认指向触发事件的DOM元素(也就是你的.uc-card容器),而这个DOM元素上并没有doSomething和scroll方法,所以会抛出TypeError。
三种可行的解决方案
1. 使用箭头函数(最简洁,推荐)
箭头函数不会创建自己的this,它会捕获外层上下文的this(也就是组件实例),完美解决指向问题:
public $onInit() { this.scroll(this.container); this.doSomething(); this.container.addEventListener('scroll', () => { console.log('scrollOnInit'); this.scroll(this.container); this.doSomething(); }); }
2. 用bind()绑定this
手动把回调函数的this绑定到组件实例,确保无论在哪里调用,this都指向组件:
public $onInit() { this.scroll(this.container); this.doSomething(); this.container.addEventListener('scroll', function() { console.log('scrollOnInit'); this.scroll(this.container); this.doSomething(); }.bind(this)); // 绑定组件实例的this }
3. 保存组件实例到变量
提前把组件实例的this存到一个变量(比如self),在回调里用这个变量代替this:
public $onInit() { const self = this; // 保存组件实例 this.scroll(this.container); this.doSomething(); this.container.addEventListener('scroll', function() { console.log('scrollOnInit'); self.scroll(self.container); // 用self访问组件方法 self.doSomething(); }); }
额外小提示
你在scroll方法里同时打印了e.scrollTop和this.container.scrollTop,其实这里的e就是你的容器元素,所以两者是等价的,选一个打印就好啦~
内容的提问来源于stack exchange,提问作者Peter Boomsma
相关产品推荐
相关产品推荐

