Add ability to send actions to components

It seems like a common problem is an inability to send some sort of action to a component. What if actions were two way streets and controllers/views could call sendAction/sendComponentAction and it would broadcast it to the components in scope subscribed to the action.

Template

{{some-comp reset="resetAction"}}

Controller/view

this.sendComponentAction('resetAction')

Component

App.SomeCompComponent = Em.Component.extend({
  actions:{
    reset:function(){};
  }
})

Right now it’s really difficult to communicate from the outside of a component inside past the creation phase. You can d ugly things, like pass a property in, observe it, when the property changes, do some action, but that’s super ugly.

I’m also interested in this. An example usecase: an audio player component you’d like to control from the controller.

How does the component know if playback was changed outside?

Edit: this is a solution GitHub - GavinJoyce/ember-component-inbound-actions: Send actions to Ember.js components

Yeah, essentially just adding a reference to the component in the parent context.

Just a note- you can listen to events on the parent controller from a component. So, if you trigger “playMedia” from the controller, you can have an event listener on the component respond to it.

Please clarify how you would implement that?

Sure! Let’s say you have a View for a button:

// Button view
click: function(){
    this.get("controller").trigger("playMedia");
}

And on your audio component:

// Audio component
playMedia: function(){
    this.$().play();
}.on("controller.playMedia")

Your controller needs to include the Ember.Evented mixin to trigger events. You could also do this with “flag properties” that you pass into the component and bind to the controller, but I think this is hacky.

Ah right, I’ll have to try that when I get around to refactoring those parts of my WebGL component. I was thinking to use a service (also using Ember.Evented) for the communication between the two, but doing it more directly like that would probably be a bit easier.

Abstracting some of that behavior into a service and giving it an API in the form of a mixin that other objects can include is how I’ve been handling application audio in an app I’ve been working on lately, and it’s terrific.