Ember.js 组件如何响应操作?

Ember.js 组件如何响应操作?,ember.js,Ember.js,tl;dr:数据可以在组件中发送和发送,但我只知道如何发送操作。是否有方法发送操作? 在我的Ember应用程序中,我有一些类似于Google Maps的UI: 背景贴图对应于一个PinsRoute/PinsView/PinsController,它显示了许多管脚。单击其中一个按钮时,输入PinRoute,该按钮将覆盖显示为{{outlet}。大地图和缩略图(在谷歌地图图像中,显示“街景”的图片)都是组件:FullscreenMapComponent和ThumbnailMapComponent

tl;dr:数据可以在组件中发送和发送,但我只知道如何发送操作。是否有方法发送操作?


在我的Ember应用程序中,我有一些类似于Google Maps的UI:

背景贴图对应于一个PinsRoute/PinsView/PinsController,它显示了许多管脚。单击其中一个按钮时,输入
PinRoute
,该按钮将覆盖显示为
{{outlet}
。大地图和缩略图(在谷歌地图图像中,显示“街景”的图片)都是组件:
FullscreenMapComponent
ThumbnailMapComponent

在谷歌地图中,当您单击“街景”时,它会将主地图平移并缩放到选定点。这基本上就是我想弄清楚如何连接的


当用户单击我的
ThumbnailMapComponent
上的“streeth view”时,我可以发送一个操作,
PinsRoute
可以处理该操作。问题是,我怎样才能找到我的
FullscreenMapComponent
并调用适当的方法(
.panToSelected()
,在这种情况下)?

这是一个有效的示例,但我不能100%肯定这种方法是最好的

以下是您可以做的:

调用操作时,将组件作为参数传递:

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');
     }
   }
});

希望这有帮助

这是一个有效的例子,但我不能100%肯定这种方法是最好的

以下是您可以做的:

调用操作时,将组件作为参数传递:

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');
     }
   }
});

希望这有帮助,这里有一个很好的解决方案。让组件将自身注册到它在其中呈现的任何控制器,这样您就可以在操作处理程序中访问组件

在我的例子中,我向组件添加了一个方法

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);
  }
}
普雷斯托!响应操作的组件

更新(10/6/2016) 哇,两年来我学到了很多

我不再推荐这种解决方案。一般来说,您应该努力使组件具有声明性,并且让它们的输出和行为完全取决于它们的状态。相反,我最初的答案是使用命令式方法解决问题的,这种方法很脆弱,很难理解,也不容易扩展(如果我们想将地图的位置与URL联系起来怎么办?)

如果我重构这个特定组件,我可能会使
{{fullscreen map}
accept
latLong
zoom
参数。如果外部有人设置了这些,地图将响应并自我更新。您可以在组件中使用
didReceiveAttrs
来响应参数更改,然后从Google的API中调用命令式
panTo
方法


要点是,即使您必须与命令式方法交互(可能是因为第三方lib),也要努力使您自己的组件的api尽可能具有声明性。第一个看似“向下发送动作”的动作通常可以表示为状态的某种函数,而这种状态正是您想要识别和明确的。

这里有一个很好的解决方案。让组件将自身注册到它在其中呈现的任何控制器,这样您就可以在操作处理程序中访问组件

在我的例子中,我向组件添加了一个方法

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);
  }
}
普雷斯托!响应操作的组件

更新(10/6/2016) 哇,两年来我学到了很多

我不再推荐这种解决方案。一般来说,您应该努力使组件具有声明性,并且让它们的输出和行为完全取决于它们的状态。相反,我最初的答案是使用命令式方法解决问题的,这种方法很脆弱,很难理解,也不容易扩展(如果我们想将地图的位置与URL联系起来怎么办?)

如果我重构这个特定组件,我可能会使
{{fullscreen map}
accept
latLong
zoom
参数。如果外部有人设置了这些,地图将响应并自我更新。您可以在组件中使用
didReceiveAttrs
来响应参数更改,然后从Google的API中调用命令式
panTo
方法


要点是,即使您必须与命令式方法交互(可能是因为第三方lib),也要努力使您自己的组件的api尽可能具有声明性。第一个看似“向下发送动作”的动作通常可以表示为状态的函数,而该状态就是您想要识别和明确的状态。

问题在于我想要响应动作的组件不是生成动作的组件,而是另一个组件(从不同的路径)。感谢您的帮助!现在,如果我的HBS模板中正在实例化
MyOtherComponent
,该怎么办?问题是我要响应操作的组件不是生成它的组件,而是不同的组件(来自不同的路径)。感谢您的帮助!现在,如果我的HBS模板中正在实例化
MyOtherComponent
,该怎么办?抱歉,这一直困扰着我-屏幕截图中的“街景”在哪里?屏幕左上角细节面板中的第一个图像抱歉,这一直困扰着我-它在哪里说“街景”在您的屏幕截图中?屏幕左上角“详细信息”面板中的第一幅图像