Javascript 键盘快捷键和Durandal对话框

Javascript 键盘快捷键和Durandal对话框,javascript,knockout.js,twitter-bootstrap-3,durandal-2.0,Javascript,Knockout.js,Twitter Bootstrap 3,Durandal 2.0,使用Durandal app.showMessage(message, title); 显示带有提供的消息和标题的模式对话框,以及单个主按钮“确定”。所有这些都是由引导程序设计的 它似乎不尊重键盘。用鼠标单击“确定”按钮按预期工作,但ESC键和ENTER键均未单击“确定”按钮 我还没有在相当简朴的Durandal文档中找到任何有用的东西,但有时这意味着它包含在子系统的文档中,如Knockout或Bootstrap 是否有人可以建议一种策略或一些与浏览器无关的常规方法,将按钮绑定到键盘快捷键 我

使用Durandal

app.showMessage(message, title);
显示带有提供的消息和标题的模式对话框,以及单个主按钮“确定”。所有这些都是由引导程序设计的

它似乎不尊重键盘。用鼠标单击“确定”按钮按预期工作,但ESC键和ENTER键均未单击“确定”按钮

我还没有在相当简朴的Durandal文档中找到任何有用的东西,但有时这意味着它包含在子系统的文档中,如Knockout或Bootstrap

是否有人可以建议一种策略或一些与浏览器无关的常规方法,将按钮绑定到键盘快捷键

我发现很难相信Durandal对话框忽略了键盘,我怀疑我是否把事情搞砸了

有那么一阵子,我想我有一个CSS指定行为的答案。它甚至在W3C文档中被指定。但它已经过时,不受支持

毫无疑问,我可以提出一个视图和视图模型模式。这将给我一个绑定其他行为的机会,我可以传递参数,几乎可以用插件替换
app.showMessage()
,但这一切似乎都相当繁重



我今天注意到空格键关闭了消息对话框。大概只有一个可聚焦控件,这就是焦点所在。鉴于Durandal的极简主义习惯,这甚至可能是出于设计,很难说。

你可以使用jwerty,可以找到。我们在Durandal项目中使用jwerty(正如RavenDB的新HTML5 Raven Studio中的Ayende Rahien一样,该工作室也是用Durandal编写的)

要查看jwerty对丰富键盘的支持,请查看我的DropBox帐户中的一个下拉日期选择器,我完全是用Durandal(和jwerty)编写的

如果您感兴趣,我可以向您展示如何将jwerty集成到Durandal中(非常简单)

[编辑]

将jwerty与Durandal结合使用有两种策略:内联和自定义淘汰绑定

内联

下面是直接来自CalendarNavigationEngine的片段:

//Bind the directional keys
    CalendarNavigationEngine.prototype.bindDirectionalKeys = function () {
        var that = this;

        var kContainerClass = this.kContainerClass;

        //Bind directional keys
        jwerty.key('left', function () { that.prevItem(); }, kContainerClass);
        jwerty.key('up', function () { that.prevWeek(); }, kContainerClass);
        jwerty.key('pgup / ctrl+left', function () { that.prevPage(); }, kContainerClass);
        jwerty.key('right', function () { that.nextItem(); }, kContainerClass);
        jwerty.key('down', function () { that.nextWeek(); }, kContainerClass);
        jwerty.key('pgdown / ctrl+right', function () { that.nextPage(); }, kContainerClass);
        jwerty.key('home', function () { that.firstItem(); }, kContainerClass);
        jwerty.key('end', function () { that.lastItem(); }, kContainerClass);
        jwerty.key('enter / tab', that.select.bind(that), kContainerClass);
    };
我们通常在viewModel上调用
bindDirectionalKeys
Durandal的
compositionComplete
处理程序。在本例中,由于CalendarNavigationEngine不是viewModel,因此调用链要深得多

内联是指直接从viewModel(或模块)进行调用,如上所示
kContainerClass
是元素上的DOM类,该元素具有焦点,应该接收和处理键盘事件

使用此方法,您需要相应的解除绑定方法:

//Unbind key bindings
    CalendarNavigationEngine.prototype.clearKeyBindings = function () {
        $(this.kContainerClass).unbind('keydown.jwerty');
    };
这将[最终]从Durandal的
分离处理程序调用,并清理
kContainerClass
上下文中的所有键绑定,以避免内存泄漏。这不是可选的

自定义敲除绑定

StackOverflow上有大量关于如何编写自定义淘汰绑定的资源。但基本上,该策略涉及将DOM元素绑定到jwerty键绑定。虽然我们没有采用这种方法(我们正在考虑),但这是非常琐碎的


有一个警告:Knockout不允许多个相同的绑定。因此不能多次调用jwerty绑定,这是将多个键绑定与单个元素关联所需的操作(如我上面给出的示例所示)。但是,您可以做的是将一个键绑定数组绑定到单个元素,然后让您的自定义敲除绑定在它的
init
处理程序中,迭代该数组,为每个项使用jwerty绑定。同样,还是很琐碎。

有趣的是,我将对此进行研究。好的,是的,我想我知道如何使用它,但我总是渴望学习。你将如何将jwerty与Durandal整合?@PeterWone如果你能给我今晚的时间,那就太好了。我今天非常忙。我将在一个新的答案中概述你可以采取的两种方法。@PeterWone看看我的答案。我给你两个策略。如果您选择后者,我可以帮助您定制绑定。