Ember中多次右键任务触发Uncaught TypeError问题求助
问题分析与解决方案
错误原因
这个报错的核心逻辑其实很好理解:当你连续右键多次时,每次都会触发一次Ember.run.later延迟任务,而当延迟任务在125ms后执行时,对应的view实例可能已经被销毁,或者它关联的DOM元素已经不存在了,这时候this.$()会返回undefined,自然就没法调用find方法,直接抛出了类型错误。
简单说就是:延迟任务“迟到”了,它要操作的对象已经被清理掉了,所以报错。
修复方案
给你两个靠谱的解决思路,任选其一都能解决右键多次触发错误的问题:
方案一:执行前先做有效性检查
在延迟任务的回调里,先判断view是否还处于可用状态,再执行聚焦操作:
Ember.run.later(view, function () { // 先确认view未被销毁、未在销毁中,且DOM元素存在 if (!this.isDestroyed && !this.isDestroying && this.$()) { this.$().find('menu-item:eq(0)').focus(); } }, 125);
isDestroyed和isDestroying是Ember内置的实例属性,专门用来判断组件/view的生命周期状态,加上this.$()的存在性检查,能彻底避免调用find时出现undefined的情况。
方案二:取消重复的延迟任务
每次右键时,先取消之前还没执行的延迟任务,避免多个任务堆积。你可以给view添加一个属性来存储延迟任务的标识:
// 假设这是你的view类代码 export default Ember.View.extend({ // 用来存储延迟任务的ID focusTimer: null, // 右键触发的处理方法 handleRightClick() { // 先取消之前未执行的延迟任务 const existingTimer = this.get('focusTimer'); if (existingTimer) { Ember.run.cancel(existingTimer); } // 创建新的延迟任务并保存ID const newTimer = Ember.run.later(this, function () { if (this.$()) { this.$().find('menu-item:eq(0)').focus(); } // 任务执行完成后清空标识 this.set('focusTimer', null); }, 125); this.set('focusTimer', newTimer); } });
这种方式会确保每次右键只会保留最后一次的延迟任务,既避免了重复执行,也从根源上减少了触发错误的概率。
新手小提示
作为Ember新手,要牢记组件/view都有明确的生命周期,异步操作(比如run.later)一定要考虑到实例是否还存活,不然很容易踩这类DOM相关的坑。另外,尽量利用Ember提供的生命周期钩子(比如didInsertElement、willDestroyElement)来管理异步任务,会更稳妥。
内容的提问来源于stack exchange,提问作者Aakash Kumar
相关产品推荐
相关产品推荐

