场景:具有自己的控制器和视图的自动完成窗口小部件,因此它是一个模块化组件,一旦移出,就可以使用{{render“autocomplete”}}或可能的新{{control}}帮助器呈现到任何其他视图中实验阶段.为了使自动完成独立于其他所有内容,它不应该知道父控制器或选择项目时发生的操作.
@H_403_2@我一直试图弄清楚如何使用Ember.Evented mixin,以便我可以触发自动完成的事件,例如itemSelected,然后可以冒泡并被父视图或控制器捕获.
@H_403_2@因此,一如既往,缺乏Ember文档.特别是当涉及到Ember.Evented. (公平地说,文档已经走了很长一段路,但我仍然想要更多.他们说没有提供约定就会使用Convention over Configuration!)无论如何,有足够的抱怨,文档显示ember在通用对象上工作,我发现这个帖子进入了更深入一点:Does EmberJs support publish/subscriber eventing pattern?但我认为一个更真实的例子,包括控制器,视图,路径和自动复合等组件会很棒.
@H_403_2@我认为这些类型的事件被认为是视图的责任,但是没有用,所以我也将mixin放在控制器上.当你看到jsFiddle时,这是有意义的
@H_403_2@在其中您将看到一个假的自动完成控制器,它只是从一个夹具中获取一组静态内容,并显示每个项目的两个按钮,您可以单击这些按钮以从视图或控制器触发事件.在一个实际例子中,将观察文本框中的输入,并且将更新内容以基于输入呈现不同的建议,但这对于该示例并不重要.
@H_403_2@jsFiddle:http://jsfiddle.net/wCfb9/
我最怀疑这些行:this.on(“myEvent”,this.addItem);
因为显然正在调用触发事件的函数,但就好像事件没有传播,或者索引控制器和视图实际上没有正确设置来响应事件. @H_403_2@以下是主要问题: @H_403_2@>我需要更改哪些内容,以便索引控制器可以响应自动完成触发的事件?
>实现这一目标的MVC最合适的方法是什么?是应该在视图/控制器上触发/接收?
>有更好的方法吗? @H_403_2@边注:
我目前的解决方案是在自动完成控制器中添加一个需求:[“index”]而不是触发事件,我只是从自动完成控制器显式调用索引控制器中的方法.这有很多问题,首先是控制器之间的紧密耦合,如果自动完成被认为影响多个控制器或者在别处重新使用并且必须重新配置等,则不能很好地扩展. @H_403_2@希望我能够清楚地解释清楚.所有帮助表示赞赏.
我最怀疑这些行:this.on(“myEvent”,this.addItem);
因为显然正在调用触发事件的函数,但就好像事件没有传播,或者索引控制器和视图实际上没有正确设置来响应事件. @H_403_2@以下是主要问题: @H_403_2@>我需要更改哪些内容,以便索引控制器可以响应自动完成触发的事件?
>实现这一目标的MVC最合适的方法是什么?是应该在视图/控制器上触发/接收?
>有更好的方法吗? @H_403_2@边注:
我目前的解决方案是在自动完成控制器中添加一个需求:[“index”]而不是触发事件,我只是从自动完成控制器显式调用索引控制器中的方法.这有很多问题,首先是控制器之间的紧密耦合,如果自动完成被认为影响多个控制器或者在别处重新使用并且必须重新配置等,则不能很好地扩展. @H_403_2@希望我能够清楚地解释清楚.所有帮助表示赞赏.
解决方法
哇,好问题.
@H_403_2@In order to make the autocomplete independent of everything else,it should not be aware of the parent controller or what action occurs when an item is selected.@H_403_2@是的,我认为你在尽可能保持孤立的方面走在正确的轨道上.
@H_403_2@Is there a better way to do this?@H_403_2@我认为可行的方法是使用RC6中引入的新“组件”功能.有关详情,请参见Ember Component API Docs. @H_403_2@使用组件方法,您可以实现独立于父控制器的自动完成目标以及选择项目时会发生什么.它非常接近内置的Ember.Select视图的运行方式.例如:
{{app-autocomplete items=model selectedItem=selectedPerson}}@H_403_2@这里我设置了autocomplete的items和selectedItem属性来绑定到当前控制器上的值. app-autocomplete不知道这些绑定的另一端是什么,或者当值发生变化时调用者将如何反应.然后,您的索引控制器可以观察它自己的selectedPerson属性,并在它发生更改时做出反应.像这样的东西:
App.IndexController = Ember.ArrayController.extend({ selectedPerson: null,selectedPersonDidChange: function() { Ember.Logger.log("Index.contoller addItem: ",this.get('selectedPerson').toString()); }.observes('selectedPerson'),});@H_403_2@该组件也非常简单.它期望它的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()); } });@H_403_2@这里有完整的例子:http://jsfiddle.net/dKUf4/