19
votes

Here's the route:

import Ember from 'ember';

export default Ember.Route.extend({
    actions: {
        closeModal: function () {
            alert('asdf');
        }
    }
});

And the component js code:

import Ember from 'ember';

export default Ember.Component.extend({
    actions: {
        closeModal: function () {
            this.sendAction('closeModal');
        }
    }
});

What I'd like to do is to (as the code may suggest ;) ) send an action from component to route, so that the route could act upon it. However the code above doesn't work - component properly handles the action, but the sendAction call inside it's method doesn't do anything.

EDIT:

I solved this problem using:

this._controller.send('closeModal'); inside component's action method however this solution doesn't satisfy me. Ember authors are saying that controllers will be removed in ember 2.0, so in my code I don't want to have any references to them. Suggestions?

1
Can you show us the template where you're using the component?GJK

1 Answers

33
votes

A component has a isolated context. So it knows nothing about anything (route or controller) outside of the component. In order to send an action from your component to your route, you should pass the route's action to the component in your template like so:

// your template
{{your-component closeModal="closeModal"}}

Now when you call this.sendAction('closeModal') in your component, it will trigger the action given to the component within your template, which in this case is the closeModal action of your route.

For more information, see the docs (http://emberjs.com/api/classes/Ember.Component.html#method_sendAction)

UPDATE August 3 2016

For those who encountered closure actions in newer versions of Ember, you might also make use of such actions here by doing:

// your template
{{your-component closeModal=(action "closeModal")}}

This action helper will point to an action of your controller, in your component you can call this.attrs.closeModal() or this.get('closeModal')() to trigger the action instead of calling sendAction.

The benefit of these actions is that the action might return a value which can be used in the component. In case of a modal this can for example be used to determine if a modal may be closed or not if the closeAction is called, if it returns false for example you might decide to prevent the modal from closing.

As a side note, the closure actions always point to your controller, in order to let it point to a route action, you might take a look at this addon: https://github.com/DockYard/ember-route-action-helper