GriffonRL
GriffonRL

Reputation: 2288

EmberJS - Calling components methods from outside with a couple solutions (call for discussion)

The following is from an issue I posted on EmberJS GitHub, but Stack Overflow is better suited for a discussion than GitHub.

I am building a few complex components at the moment including composite components and I hit a roadblock with the extreme isolation components live in. There are several cases where I don't need the components to trigger an action on a controller, but where a controller needs to trigger a behaviour change on the component. Problems is that the components don't know about the controller and the controller is not creating the components either: they are defined in a template.

I kind of solved the problem by subclassing the Ember.Component class to offer a way for messages to get through components.

The new component subclass breaks the on purpose isolation of components that shouldn't know about the outer controller. The 2 less invasive options I found to make component methods calls from outside are:

My question is about how could we solve this problem in the most elegant and less invasive way possible for components ? For achieving composite components, using the components like lego pieces, it seems impossible to me at the moment to see how we can achieve that goal without breaking the components isolation.

Any input, ideas, solutions, discussion is very welcome.

Note: By the way, the first method that breaks the component isolation is inspired by the work done on the ember-bootstrap components: https://github.com/ember-addons/bootstrap-for-ember The author had to solve the same problem of being capable of triggering methods inside the components from outside.

Another note: Just for the record, another way to access a component is to use Ember.View.views['name'] where name is a view name you gave to your component. However I feel dirty to make such calls, even more from a controller.

Upvotes: 3

Views: 2124

Answers (1)

Dan Gebhardt
Dan Gebhardt

Reputation: 3281

In general, I would try to solve this by binding properties to your component, which could then change according to computed properties or observers based on those properties.

For instance, instead of trying to call a method like deactivate on a component, bind a property such as active to a property in the template:

{{my-component active=formEnabled}}

I'm hesitant to recommend passing an eventSource to components as a general solution (like your {{my-component eventSource=controller}} example). I imagine this could work with a class or mixin that just emits specific events and is tightly coupled with your component, but I'm struggling to come up with a use case that justifies this approach.

Upvotes: 3

Related Questions