键盘快捷键和Durandal对话框

时间:2014-06-09 09:56:38

标签: javascript knockout.js twitter-bootstrap-3 durandal-2.0

使用Durandal,

app.showMessage(message, title);

显示带有提供的消息和标题的模态对话框,以及单个主按钮OK。所有这些都是由Bootstrap设计的。

它似乎不尊重键盘。单击确定按钮,鼠标按预期工作,但ESC和ENTER键都没有单击确定按钮。

我还没有在Spartan Durandal文档中找到任何有用的东西,但有时候这意味着它被Knockout或Bootstrap等子系统的文档所覆盖。

任何人都可以建议一种策略或一些相关的阅读习惯浏览器独立方式将按钮绑定到键盘快捷键?

我发现很难相信Durandal对话框会忽略键盘,我不知道我是否搞砸了。

我想我在CSS指定的行为中有一个答案。它甚至在W3C文档中指定。但它已经过时而且不受支持。

毫无疑问,我可以提供一个视图并以模态方式查看模型。这将使我有机会绑定其他行为,我可以传递参数,几乎插件替换app.showMessage(),但这一切似乎都很重。


我今天注意到空格键关闭了消息对话框。据推测只有一个可调焦的控件,那就是焦点所在。考虑到Durandal的极简主义习惯,这甚至可能是设计上的,很难说。

1 个答案:

答案 0 :(得分:3)

您可以使用jwerty,可以找到here。我们在Durandal项目中使用jwerty(和RavenDB的新HTML5 Raven Studio中的Ayende Rahien一样,也是用Durandal编写的)。

要查看使用jwerty的丰富键盘支持,take a look at this video在我使用Durandal(和jwerty)完全编写的Dropdown Datepicker的DropBox帐户上。

如果你有兴趣,我可以告诉你如何将jwerty融入Durandal(非常简单)。

<强> [编辑]

在Durandal中使用jwerty有两种策略:内联自定义Knockout绑定

<强> INLINE

以下是我们的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,因此调用链更深。

通过 inline 我的意思是说你直接从你的viewModel(或模块)进行调用,如上所示。 kContainerClass是元素或元素上的DOM类,它具有焦点,应该接收和处理键盘事件。

使用这种方法,您需要一个相应的解除绑定方法:

//Unbind key bindings
    CalendarNavigationEngine.prototype.clearKeyBindings = function () {
        $(this.kContainerClass).unbind('keydown.jwerty');
    };

这将[最终]从Durandal的detached处理程序调用,并清除kContainerClass上下文中的所有键绑定以避免内存泄漏。这不是可选的。

CUSTOM KNOCKOUT BINDING

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

有一点需要注意:Knockout不允许多个相同的绑定。所以你不能多次调用jwerty绑定,这是你需要做的,以便将多个键绑定与一个元素相关联(如我上面给出的例子)。但是,您可以做的是将键绑定的数组绑定到单个元素,然后在其init处理程序中使用自定义Knockout绑定迭代该数组,绑定每个项目的jwerty。再次,仍然是微不足道的。