tl; dr:数据可以发送进出组件,但我只知道如何发送动作.有没有办法发送行动?
在我的Ember应用程序中,我有类似Google地图中的以下用户界面:

背景图对应于PinsRoute/PinsView/PinsController,它显示了许多引脚.单击其中一个时,输入PinRoute将叠加层渲染到的窗口{{outlet}}.大地图和缩略图(在Google地图图片中,显示"街景"的图片)都是组件:FullscreenMapComponent和ThumbnailMapComponent.
在Google地图中,当您点击"街景视图"时,它会将主地图平移并缩放到所选点.这基本上就是我想弄清楚如何连线.
当用户点击我的"streeth view"时ThumbnailMapComponent,我可以发出一个PinsRoute可以处理的动作.问题是,我怎样才能找到我的FullscreenMapComponent并调用适当的方法(.panToSelected()在这种情况下)?
这是一个很好的解决方案.让组件将其自身注册到呈现的任何控制器,这样您就可以在操作处理程序中访问该组件.
在我的例子中,我为我的组件添加了一个方法
App.FullscreenMapComponent = Ember.Component.extend({
...
_register: function() {
this.set('register-as', this);
}.on('init')
});
Run Code Online (Sandbox Code Playgroud)
和我的控制器的属性:
App.SensorsController = Ember.ArrayController.extend({
fullscreenMap: null,
...
});
Run Code Online (Sandbox Code Playgroud)
在我的模板中,我将两个绑定到我的新register-as属性:
// sensors.hbs
{{fullscreen-map data=mapData
selectedItem=currentSensor
action='selectSensor'
deselect='deselectSensor'
register-as=fullscreenMap }}
Run Code Online (Sandbox Code Playgroud)
现在,假设我点击上面的缩略图并发送一个冒泡到我的动作ApplicationRoute,我现在可以这样做:
// ApplicationRoute.js
actions: {
panTo: function(latLong, zoom) {
this.controllerFor('sensors').get('fullscreenMap').panTo(latLong, zoom);
}
}
Run Code Online (Sandbox Code Playgroud)
普雷斯托!响应操作的组件.
哇,我在两年内学到了很多东西.
我不再推荐这个解决方案了.通常,您应该努力使组件具有声明性,并使其输出和行为完全取决于其状态.相反,我在这里的原始答案使用命令式方法解决了问题,这种方法很脆弱,难以理解,并且不容易扩展(如果我们想将地图的位置与URL联系起来怎么办?).
如果我重构这个特定的组件,我可能会{{fullscreen-map}}接受latLong和zoomparams.如果来自外部的人设置了这些,则地图将响应并自行更新.您可以didReceiveAttrs在组件内使用以响应参数更改,然后从那里调用panToGoogle API 的命令式方法.
需要注意的是,即使您必须与命令式方法(可能是因为第三方库)进行交互,也要努力使自己的组件API尽可能具有声明性.首先看起来"向下发送一个动作"通常可以表示为状态的某种功能,并且该状态是您想要识别和明确的状态.