11

I've created a set of nested components.

The code is here: http://emberjs.jsbin.com/hasehija/2/edit.

HTML:

{{#level-1}}
    {{#level-2}}
      {{#level-3}}
        <button {{action 'handleAction'}}>
          Click me (yielded)
        </button>
      {{/level-3}}
    {{/level-2}}
 {{/level-1}}

JS:

App.ApplicationController = Ember.Controller.extend({
  actions: {
    handleAction: function() {
      alert('Handled in ApplicationController');
    }
  }
});

App.Level1Component = Ember.Component.extend({
  actions: {
    handleAction: function() {
      alert('Handled in Level 1');
    }
  }
});

App.Level2Component = Ember.Component.extend({
  actions: {
    handleAction: function() {
      alert('Handled in Level 2');
    }
  }
});

App.Level3Component = Ember.Component.extend({
  actions: {
    handleAction: function() {
      alert('Handled in Level 3');
      this.set('action', 'handleAction');
      this.sendAction();
    }
  }
});

What I want to achieve is to bubble the events in the following way:

Level3Component -> Level2Component -> Level1Component -> ApplicationController

Unfortunately, I cannot handle the events inside any of the components; the event bubbled up to ApplicationController.

Is there a way to force Components' actions to bubble over the whole hierarchy of components, so that I have the alert shown 4 times (after adding this.sendAction of course)?

Once again, here's a code that you can play with: http://emberjs.jsbin.com/hasehija/2/edit.

andrusieczko
  • 2,824
  • 12
  • 23

2 Answers2

19

Based on your example, you must define the component targetObject property as:

App.Level3Component = Ember.Component.extend({
  action: 'handleAction',
  targetObject: Em.computed.alias('parentView'),  
  actions: {
    handleAction: function() {
      alert('Handled in Level 3');
      this.sendAction();
    }
  }
});

http://emberjs.jsbin.com/hasehija/5/edit

ppcano
  • 2,831
  • 1
  • 24
  • 19
  • 1
    Thank you! It answers my question entirely! I'm wondering if the thing with the most inner button is really a bug. – andrusieczko Jun 05 '14 at 13:00
  • Hmm, probably it's not a bug... The "Click me (inside of component)" button calls `Level3Component`, not `Level2Component` so exactly in the place where it was defined. I think it's a proper behavior. – andrusieczko Jun 05 '14 at 13:11
  • I was talking about "Click me (yielded)", it should target the component instead of the ApplicationController – ppcano Jun 05 '14 at 19:00
  • 1
    I was wrong, this is the default behaviour. There is a test which describes this case "Inside a yield, the target points at the original target" https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/tests/helpers/action_test.js#L117 – ppcano Jun 05 '14 at 19:22
0

If I understand the question correctly, this question is related and the answer shows how you can do it from the template--you may be able to do:

{{#level-1}}
    {{#level-2 targetObject=view}}
      {{#level-3 targetObject=view}}
        <button {{action 'handleAction'}}>
          Click me (yielded)
        </button>
      {{/level-3}}
    {{/level-2}}
 {{/level-1}}

Handy if you don't control the inner components or don't want to modify them directly as the other answer does.

I think the reason you say view here instead of parentView in the above answer is due to Handlebars treating view as a special keyword...in any case, using parentView in the template didn't work (which puzzles me, but whatever).

Community
  • 1
  • 1
S'pht'Kr
  • 2,809
  • 1
  • 24
  • 43