在Aurelia viewmodel组件中,我有以下JQuery代码,可以在模态可见时捕获Ctrl S或Ctrl Enter并调用save函数:
$(window).bind('keydown', function(event) {
if (event.ctrlKey || event.metaKey) { // Ctrl + ___
if ((event.which == 83) || (event.which == 115) || (event.which == 10) || (event.which == 13)) { // Ctrl+Enter or Ctrl+S
// Save button
event.preventDefault();
if ($(self.edit_calendar).is(':visible')) {
self.saveCalendar();
}
}
}
});
但是,我预计会在40个视图模型中添加一个类似的功能,这看起来不是很干,并且为每个视图模型添加了一些丑陋的代码 . 我想在单例类中创建一个通用的addEventListener函数,以便从我的每个视图中轻松调用 . 这就是我的想法:
addListenerSave(visible, callback) {
// Add an event listener to redirect keyboard shortcuts to specific actions
console.log("addListenerSave()");
$(window).bind('keydown', function(event) {
if (event.ctrlKey || event.metaKey) { // Ctrl + ___
if ((event.which == 83) || (event.which == 115) || (event.which == 10) || (event.which == 13)) { // Ctrl+Enter or Ctrl+S
// Save button
event.preventDefault();
if ($(visible).is(':visible')) {
console.log("Keyboard shortcut: Save");
callback();
}
}
}
});
}
然后,在我的各个组件中,我只需要在实例化时使用以下代码(在附件()组件生命周期中):
this.config.addListenerSave(this.edit_calendar, this.saveCalendar);
但是,这不起作用 . saveCalendar()被调用但可能来自另一个范围/上下文,所以我在saveCalendar中得到一个错误,表示"Cannot read property 'selectedId' of undefined" . 这是指saveCalendar()代码 if (this.selectedId)...
. 我究竟做错了什么?
最后,当我的Aurelia组件分离时,我是否还应该删除此事件侦听器?怎么样?
我有一个不同的想法是使用Aurelia的eventAggregator创建一个全局事件监听器,它始终监听Ctrl S / Ctrl Enter,然后发布可以在每个组件中订阅的消息 .
2 回答
我成功实现了添加全局事件侦听器的备用解决方案,该侦听器使用Aurelia的EventAggregator来共享Ctrl S / Ctrl Enter . 原始问题仍然存在,但也许它不是最好的方法 . 这是我的解决方案:
config.js (全球单身人士班)
然后,在我的组件viewmodel calendar.js 中:
像魅力一样工作,现在我可以自由添加更多的组件事件监听器,甚至可以扩展功能,为Ctrl F(for find)等添加全局监听器 .
为了回答你原来的问题,你走在正确的轨道上 - 但是由于JavaScript中
this
的语义,你来自C#的观点,它可能有助于认为JavaScript中的所有函数本质上都是扩展方法;因此,传递函数可能非常强大 . )由于新的ES6类语法,很容易错过这个 .这应该可以缓解您的问题:
也就是说,使用Aurelia的Event Aggregator的解决方案更适合您的用例并且更具可扩展性 . 我想我会发布这个答案来解决原始问题,这只是功能范围的问题 .