2
votes

I have a component that need to receive an action that I placed on the route since its job is to refresh part of the model.

Apparently I can call the route action from a button but I am not able to pass the same action down to the component.

The router

export default Ember.Route.extend({
    actions: {
        doSomething: function(){
            alert('Router handled!');
        }
    }
});

The page template

<button {{action "doSomething"}}>speak</button>
{{myComponent onGetUsers=(action "doSomething")}}

The component

export default Ember.Component.extend({
    actions: {
        onPageClicked: function(pageNo){
            this.sendAction('onGetUsers', pageNo);
        }
    }
});

The button click works. When I use the component I make it to its action but the sendAction never work or fires.

Is there a rule that I cannot pass actions to down line components? or am I doing something wrong in the code?

2
I was able to fire the router by using an action on the controller by using this.send() rather then this.sendAction() but I still would like to know why sending the router action down to the component does not work. If possible.hal9000

2 Answers

3
votes

sendActions - can be used for component to Component communication.
send - can be used for controller to route communication. You can't use either way.

For Component to route communication, you can use below addon.

ember install ember-route-action-helper

By defining action in route, you can call it from template.hbs

<button {{action (route-action 'appRouteAction' 'fromApplication.hbs') }}>button</button>

and You can call from my-component.hbs

<button {{action (route-action 'appRouteAction' 'from MyComponent.hbs') }}>My-Component button</button>

and If you would like to call Component action first and then action in route,

In template.hbs - include Component with route-action as closure action,

{{my-component2 appRouteAction=(route-action 'appRouteAction')}}

In my-compoent2.hbs,

<button {{action 'appRouteAction' 'CallFromComponentActions-my-compoent2.hbs' }}>CallFromComponentActions</button>

In my-compoent2.js

import Ember from 'ember';
export default Ember.Component.extend({
  actions:{
    appRouteAction(fromWhere){
      console.log('appRouteAction in my-component ');
      this.get('appRouteAction')(...arguments);
    }
  }
});

Sample Twiddle- to play around ember-route-action-helper-addon.

1
votes

sendAction is kind of an old concept. It's still functional, but it's basically been superseded by closure actions which it seems like you're aware of.

The reason it currently doesn't work for the route actions is because of trying to create a closure for an unknown target. At the time the template is inserted into the DOM, the closure action tries to identify the exact function and target it fire when invoked. This is done for simplicity and so that the action can return a value. When that action is on a controller or a parent component, it's very easy. When that action is on a route, it's not so easy because it would have to walk the route chain to find the nearest route implementing that action. Also since route actions can return false to allow the action to bubble further, it would be tricky to fully support.

There is an ember-cli addon that will help bridge this gap though. Checkout: https://github.com/DockYard/ember-route-action-helper. Here is a JSBin showing it in action: http://jsbin.com/luruyegice/edit?html,js,output