Javascript 如何使用ember.js捕捉列表中某个项目的按键事件?
我正在努力提高我编写的应用程序的可访问性。我也在学习更多关于余烬的知识。作为练习,我将使用()添加一些功能,以帮助屏幕阅读器的用户 我想了解的一件事是如何从键盘触发对待办事项的编辑。保存项目标题的Javascript 如何使用ember.js捕捉列表中某个项目的按键事件?,javascript,ember.js,accessibility,Javascript,Ember.js,Accessibility,我正在努力提高我编写的应用程序的可访问性。我也在学习更多关于余烬的知识。作为练习,我将使用()添加一些功能,以帮助屏幕阅读器的用户 我想了解的一件事是如何从键盘触发对待办事项的编辑。保存项目标题的元素可以聚焦,然后按下回车键进入编辑模式。在演示中,只需双击即可打开该项目进行编辑。此行为由操作助手处理,据我所知,该助手专门用于使元素可单击。下面是有问题的模板部分。我省略了代码的功能,以删除不相关的逻辑: {{#each itemController="todo"}} <li ... &g
元素可以聚焦,然后按下回车键进入编辑模式。在演示中,只需双击
即可打开该项目进行编辑。此行为由操作
助手处理,据我所知,该助手专门用于使元素可单击。下面是有问题的模板部分。我省略了代码的功能,以删除不相关的逻辑:
{{#each itemController="todo"}}
<li ... >
...
{{input type="checkbox" checked=isCompleted class="toggle"}}
<label {{action "editTodo" on="doubleClick"}}>{{title}}</label>
...
</li>
{{/each}}
{{#each itemController=“todo”}
...
{{input type=“checkbox”checked=isCompleted class=“toggle”}
{{title}}
...
{{/每个}}
“不要使用操作
助手”似乎是开始的地方。但现在处理每一项的最佳方式是什么
正如每个
帮助程序中的itemController=“todo”
所示,有一个TodoController
(它扩展了ObjectController
)定义了一个editTodo
函数。我想要一个按键事件触发器来实现这个功能。(目前,我们可以忽略对事件的检查,只捕获Enter/Retrun键。)
我已经在label元素中添加了tabindex=“0”
,似乎我可以用键盘对其进行对焦。我已尝试将keyPress
函数添加到TodoController
的actions
散列中,但当我按键时它不会被触发。我认为这是因为每个项目都没有真正的视图
——todo和模板的ArrayController
似乎在处理todo项目之间的显示
我今天读了很多书,似乎需要为每个项目指定一个视图
,可能需要使用ContainerView
并指定其itemViewClass
属性,以便在插入视图时可以聚焦视图。但是ember站点上的示例并没有使用each
helper:它们有较低级别的机制来添加渲染视图,我怀疑这不是当前的最佳实践
我怀疑有不止一种方法可以做到这一点,但我还是太新的余烬想不出来。我认为解决这个问题将对框架有很大的启发
如何将按键支持添加到演示中进行编辑?最简单的方法是将
on=“click”
事件绑定更改为on=“keyPress”
。您可以在此处找到受支持事件的列表:
正如您已经提到的,您必须在label元素上使用tabindex hack。但在Chrome中,标签似乎是不可标记的——Firefox和IE都可以
{{#each itemController="todo"}}
<li ... >
...
{{input type="checkbox" checked=isCompleted class="toggle"}}
<label {{action "editTodo" on="keyPress"}}>{{title}}</label>
...
</li>
{{/each}}
{{#each itemController=“todo”}
...
{{input type=“checkbox”checked=isCompleted class=“toggle”}
{{title}}
...
{{/每个}}
感谢@Oliver和@MatthewBlanchert为我指明了正确的方向。我最终将操作
帮助程序替换为一个视图
帮助程序,该帮助程序为标签包装代码
我只需要标签
上的特定行为,而不需要整个li
或替换标签的输入
字段上的特定行为。我很高兴地发现视图不需要模板:我只需编写一个模板来添加我想要的行为,然后将标记放入TODO的现有模板中。下面是它的样子:
- <label {{action "editTodo" on="doubleClick"}}>{{title}}</label>
+ {{#view "Todos.TodoLabelView"}}
+ <label tabindex="0">{{title}}</label>
{{/view}}
这将使用单独的处理程序保留双击时的编辑行为
最后,我注意到在呈现文本字段后,[Enter]键被应用于文本字段,这会立即关闭该字段并将标签返回给DOM。我尝试从我的按键
方法以及事件#停止播放
返回false
。我甚至将对控制器的editto
方法的调用设置为超时。不好
我必须从自定义编辑todo
处理程序中删除insert newline=“acceptChanges”
,并在edittoview
中按[Enter]键:
Todos.TodoLabelView = Ember.View.extend({
keyPress: function(ev) {
if (ev.keyCode === 13) {
this.get("controller").send("editTodo");
}
},
doubleClick: function() {
this.get("controller").send("editTodo");
},
});
doubleClick: function() {
this.get("controller").send("editTodo");
}
我很想听听大家对我的解决方案的意见,特别是如果有一种更简单的方法,或者我忽略了一些重要的东西。您可以扩展内置的帮助程序来实现您的目标:您希望将事件驱动的操作放入您正在使用的任何帮助程序类型的扩展中。我还应该说,您可以使用
this.get从视图中访问当前控制器(“控制器”)
或甚至父控制器。这将使您能够访问项目控制器中所需的内容。@MatthewBlancarte我的新手身份正在显示,但我不确定如何按照您的建议扩展助手。我知道。这使我认为使用按键
方法的视图会很好。我应该如何在此处引入显式视图?似乎没有帽子助手可以插入一个视图(或者你可以使用视图助手本身)。很抱歉,你很迟钝,但是你能给我指出更多的信息或例子吗?是的,你的思路是对的。视图实际上只负责渲染一个模型,所以它有权访问它是合乎逻辑的(在您的例子中,您希望为todo集合中的每个循环模型生成一个视图)。请尝试App.MyText=Ember.TextField.extend({})
并将按键操作处理程序放在其中。在您的操作中,尝试,console.log(this.get('controller.content'))
希望这能说明视图和控制器是如何交互的。您也可以创建自己的自定义组件,但可以从g的helper扩展开始