How to communicate to child components

When you really want something like a “global event bus”, that’s a Service. You can Ember.inject.service() on any components that need to access it, and then just access it directly. They will all share it.

When you have a parent component with some tightly-coupled children, you can yield values to the children that give them a way to interact with the parent. For example:

{{#my-super-form as |parent|}}
    {{some-child notify=parent}}
{{/my-parent-component}}

Then the child can decide to this.get('notify').send('somethingHappened'). If you want to be able to send actions from parent-to-child, you can have the children register themselves at didInsertElement.

It’s also possible to yield functions and write child components that just call those functions:

{{#my-form as |submit cancel|}}
  {{#my-button action=submit}}Go{{/my-button}}
  {{#my-button action=cancel}}Nevermind{{/my-button}}
{{/my-form}}

Today this requires some small hacks. In 2.0, it will work this way out of the box – the parent’s template can just say {{yield (action "submit") (action "cancel")}}, and the children will receive functions they can call directly.

In general I would avoid trying to send actions downward. Remember, it’s actions up, data down. Design the flow so you’re just pushing new data down to the children and they will react appropriately. In your form-reset case, instead of storing the original values in the children and telling them to reset themselves, store the original values in the parent and share both the current values and the original values with the children, so they always know whether to show the has-been-edited style or not.

8 Likes