tl; dr:数据可以发送进出组件,但我只知道如何发送操作。有没有办法发送行动?
在我的Ember应用程序中,我有类似Google地图中的以下用户界面:
背景图对应于PinsRoute / PinsView / PinsController,它显示了许多引脚。点击一个后,输入PinRoute
,将叠加层渲染为{{outlet}}
。大地图和缩略图(在Google地图图片中,图片中显示"街景")分别是:FullscreenMapComponent
和ThumbnailMapComponent
。
在Google地图中,当您点击"街景"时,它会将主地图平移并缩放到所选点。这基本上就是我试图弄清楚如何连线。
当用户点击"延伸视图"在ThumbnailMapComponent
上,我可以发送PinsRoute
可以处理的操作。问题是,我怎样才能到达我的FullscreenMapComponent
并调用适当的方法(在这种情况下为.panToSelected()
)?
答案 0 :(得分:6)
这是一个很好的解决方案。让组件将自己注册到呈现它的任何控制器,这样你就可以在动作处理程序中访问该组件。
就我而言,我在组件中添加了一个方法
App.FullscreenMapComponent = Ember.Component.extend({
...
_register: function() {
this.set('register-as', this);
}.on('init')
});
和我的控制器的属性:
App.SensorsController = Ember.ArrayController.extend({
fullscreenMap: null,
...
});
在我的模板中,我将两者绑定到我的新register-as
属性:
// sensors.hbs
{{fullscreen-map data=mapData
selectedItem=currentSensor
action='selectSensor'
deselect='deselectSensor'
register-as=fullscreenMap }}
现在,让我说我点击上面的缩略图,它会发送一个冒泡到ApplicationRoute
的动作,我现在可以这样做了:
// ApplicationRoute.js
actions: {
panTo: function(latLong, zoom) {
this.controllerFor('sensors').get('fullscreenMap').panTo(latLong, zoom);
}
}
的Presto!响应行动的组件。
哇,我在两年内学到了很多东西。
我不再推荐这个解决方案了。通常,您应该努力使组件具有声明性,并使其输出和行为完全取决于其状态。相反,我在这里的原始答案使用命令式方法解决了问题,这种方法很脆弱,难以理解,并且不容易扩展(如果我们想将地图的位置与URL联系起来怎么办?)。
如果我正在重构此特定组件,我可能会{{fullscreen-map}}
接受latLong
和zoom
参数。如果来自外部的人设置了这些,则地图将响应并自行更新。您可以在组件中使用didReceiveAttrs
来响应参数更改,然后从那里调用Google API中的命令式panTo
方法。
需要注意的是,即使你必须与命令式方法交互(可能是因为第三方库),也要努力使自己组件的API尽可能具有声明性。首先看起来“向下发送一个动作”通常可以表示为状态的一些功能,并且该状态是您想要识别和明确的状态。
答案 1 :(得分:1)
这是一个有效的例子,但我并不是100%确定这种方法是最好的
你可以做什么:
调用action时,将组件作为参数传递:
App.PinController = Ember.Controller.extend({
actions: {
actionThatComponentCalls: function(){
// different component will be called
new App.MyOtherComponent().send('differentAction'):
}
}
});
App.FullScreenMapComponent = Ember.Component.extend({
click: function(){
this.sendAction();
}
});
App.MyOtherComponent = Ember.Component.extend({
actions: {
differentAction: function(){
console.log('different action called');
}
}
});
希望这有帮助