Ember.js 如何在Emberjs中的控制器之间传递事件?更新:如何在余烬中设计自动完成
场景:一个具有自己的控制器和视图的自动完成小部件,因此它是一个模块化组件,一旦移出实验阶段,就可以使用{render“autocomplete”}或新的{control}助手将其呈现到任何其他视图中。为了使自动完成独立于其他所有内容,它不应该知道父控制器,也不应该知道在选择某个项时会发生什么操作 我一直在试图弄清楚如何使用Ember.Evented mixin,这样我就可以从自动完成触发一个事件,比如itemSelected,然后它会冒泡出来并被父视图或控制器捕获 所以像往常一样,Ember文档是缺乏的。尤其是在余烬事件方面。(公平地说,文档已经走过了很长一段路,但我仍然想要更多。他们说约定优于配置,但没有提供约定!)总之,抱怨够了,文档显示了ember evented在通用对象上的工作,我发现这篇文章更深入了一点:但我认为一个带有控制器、视图、路由和组件(如autocompletes)的更真实的示例会更好 我认为这些类型的事件应该是视图的责任,但这不起作用,所以我也将mixin放在了控制器上。当您看到jsFiddle时,这将是有意义的 在其中,您将看到一个假的autocomplete控制器,它只是从设备中获取一组静态内容,并为每个项目显示两个按钮,您可以单击这些按钮从视图或控制器触发事件。在一个实际示例中,将观察文本框中的输入,并更新内容,以根据输入提供不同的建议,但这对于本示例并不重要 jsFiddle: 我最怀疑这些行:Ember.js 如何在Emberjs中的控制器之间传递事件?更新:如何在余烬中设计自动完成,ember.js,Ember.js,场景:一个具有自己的控制器和视图的自动完成小部件,因此它是一个模块化组件,一旦移出实验阶段,就可以使用{render“autocomplete”}或新的{control}助手将其呈现到任何其他视图中。为了使自动完成独立于其他所有内容,它不应该知道父控制器,也不应该知道在选择某个项时会发生什么操作 我一直在试图弄清楚如何使用Ember.Evented mixin,这样我就可以从自动完成触发一个事件,比如itemSelected,然后它会冒泡出来并被父视图或控制器捕获 所以像往常一样,Ember文档
this.on(“myEvent”,this.addItem)代码>
因为触发事件的函数显然正在被调用,但似乎事件没有传播,或者索引控制器和视图实际上没有正确设置以响应事件
以下是主要问题:
我需要更改什么,以便索引控制器能够响应自动完成触发的事件
实现这一点最适合MVC的方式是什么?触发/接收是否应在视图/控制器上
有更好的方法吗
旁注:
我目前的解决方案是在自动完成控制器中添加needs:[“index”]
,而不是触发事件,我只是从自动完成控制器显式调用index控制器中的方法。这有很多问题,首先是控制器之间的紧密耦合,如果假设自动完成会影响多个控制器,或者在其他地方重复使用,并且必须重新配置等,则无法很好地扩展
希望我解释得足够清楚。感谢您的帮助。哇,好问题
为了使自动完成独立于其他所有内容,它不应该知道父控制器,也不应该知道在选择某个项时会发生什么操作
是的,我认为你在尽可能地保持事物孤立方面走在了正确的轨道上
有更好的方法吗
我认为是的,应该使用RC6中引入的新“组件”功能。有关详细信息,请参阅
使用组件方法,您可以实现自动完成独立于父控制器的目标,以及选择项时发生的情况。这与内置的Ember.Select视图的操作非常接近。例如:
{{app-autocomplete items=model selectedItem=selectedPerson}}
在这里,我设置了自动完成的项,并选择了editem属性以绑定到当前控制器上的值。appautocomplete不知道这些绑定的另一端是什么,也不知道当值发生变化时调用方将如何反应。然后,您的索引控制器可以观察它自己的selectedPerson属性,并在其更改时作出反应。大概是这样的:
App.IndexController = Ember.ArrayController.extend({
selectedPerson: null,
selectedPersonDidChange: function() {
Ember.Logger.log("Index.contoller addItem: ", this.get('selectedPerson').toString());
}.observes('selectedPerson'),
});
组件也非常简单。它希望它的items
属性包含一个具有名称的对象数组,当单击一个时,它会设置自己的selectedItem
属性
<script type="text/x-handlebars" id="components/app-autocomplete">
{{input}}
{{#each item in items}}
<li><button {{action itemSelected item}}>{{item.name}}</button></li>
{{/each}}
</script>
App.AppAutocompleteComponent = Ember.Component.extend({
itemSelected: function (item) {
this.set("selectedItem", item);
Ember.Logger.log("component.itemSelected: myEvent triggered wit h: ", item.toString());
}
});
{{input}}
{{{#项目中的每个项目}
{{item.name}
{{/每个}}
App.AppAutocompleteComponent=Ember.Component.extend({
所选项目:功能(项目){
此.set(“selectedItem”,项);
Ember.Logger.log(“component.itemSelected:myEvent被h触发:”,item.toString());
}
});
这里的完整示例:根据Mike Grassotti的建议,我们认为Ember.Evented实际上不是正确的解决方案,并开始研究{{control}}和Ember.Component
我仍然不确定他发布的JSFIDLE链接,但我从他的帖子中获得了足够的信息,并创建了一个jsBin来模拟使用{{control}}和使用Ember.Component的尝试。每个组件都有优点和缺点,但最终,Ember.Component获胜,因为{{control}}没有正确绑定
见:
(我不知道如何在JSFIDLE中设置ENV.EXPERIMENTAL_CONTROL_HELPER,这就是为什么我使用jsBin,最终我更喜欢jsBin的原因…)
在其中,您将看到两个自动完成。一个是用{control}}助手实现的,它使用一个AutocompleteController和AutocompleteView,另一个是Mike Grassotti建议的Ember.Component
#1使用{{control}助手:
优点:我喜欢为自动完成设置控制器的想法,因为我认为这是一种更好的分离关注点/单一责任的方法。自动完成控制器应该知道如何处理输入框中的文本,如何发送请求,以及在需要时解析数据
缺点:我遇到的第一个问题是控件助手似乎需要