在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中得到一个错误,说明"无法读取属性' selectedId'未定义"。这是指saveCalendar()代码if (this.selectedId)...
。我做错了什么?
最后,当我的Aurelia组件分离时,我是否还应该删除此事件侦听器?怎么样?
我的另一个想法是使用Aurelia的eventAggregator创建一个全局事件监听器,它始终监听Ctrl + S / Ctrl + Enter,然后发布可以在每个组件中订阅的消息。
答案 0 :(得分:1)
要回答原始问题,您已走上正轨 - 但由于JavaScript中this
的语义,您需要绑定您的功能。 (如果您来自C#视角,那么认为JavaScript中的所有函数本质上都是扩展方法可能会有所帮助;因此,传递函数可能非常强大。)因为它很容易错过新的ES6类语法。
这可以缓解您的问题:
this.config.addListenerSave(this.edit_calendar, this.saveCalendar.bind(this));
也就是说,使用Aurelia的Event Aggregator的解决方案更适合您的用例并且更具可扩展性。我以为我发布这个答案来解决原始问题,这只是功能范围问题。
答案 1 :(得分:0)
我成功实现了添加全局事件侦听器的备用解决方案,该侦听器使用Aurelia的EventAggregator来共享Ctrl + S / Ctrl + Enter。原始问题仍然存在,但也许它不是最好的方法。这是我的解决方案:
config.js (全球单身人士)
@inject(EventAggregator)
export class Config {
constructor(eventAggregator) {
var self = this;
this.eventAggregator = eventAggregator;
// listen for Ctrl+S or Ctrl+Enter and publish event
window.addEventListener("keydown", function(event) {
if (event.ctrlKey || event.metaKey) { // Ctrl + ___
if ((event.keyCode == 83) || (event.keyCode == 115) || (event.keyCode == 10) || (event.keyCode == 13)) { // Ctrl+Enter or Ctrl+S
// Save button
console.log("Publishing ewKeyboardShortcutSave...");
event.preventDefault();
self.eventAggregator.publish('ewKeyboardShortcutSave', true);
}
}
});
}
}
然后,在我的组件viewmodel calendar.js :
中@inject(EventAggregator)
export class Calendar {
constructor(eventAggregator) {
this.eventAggregator = eventAggregator;
}
attached() {
var self = this;
// Ctrl+Enter is save
this.eventAggregator.subscribe('ewKeyboardShortcutSave', response => {
console.log("I heard ewKeyboardShortcutSave: " + response);
if ($(self.edit_calendar).is(':visible')) {
self.saveCalendar();
}
});
}
}
像魅力一样工作,现在我可以自由添加更多组件事件监听器,甚至可以扩展功能,为Ctrl + F(用于查找)等添加全局监听器。