Charles Charles - 5 months ago 24
Javascript Question

EmberJS - How not to conflict with actions and events in components

I think there is a an issue between template actions and events in components.

As far as I understand all action clicks will be first executed and bubbled.
Finally events in components will be also executed.
There are like two parallel stacks executed one after the other.

If you have something like this in the template of a component:

Hello <button onclick={{action 'clickMe'}}>Click me</button>

and this in the corresponding javascript file:

click: function() {
alert('second message');

You are not sure that the second message will be displayed. If event.stopPropagation() is called in the stack of action (not necessary inside the action 'clickMe'), the second message won't be shown.

Here is a twiddle:

Is there a solution to bypass this problem?

Answer Source

When you say, <button onclick={{action 'clickMe'}}>Click me</button> - its nothing to do with ember, its just normal function registered for the click event.

When you say, <button {{action 'clickMe'}}>Click me</button> here Ember will take control(I am not sure what I am talking about, but generally speaking event processing will be handled by Ember).

twiddle1 - Ember is handling the all the event handling(ie.,<div {{action 'test'}}> then you can expect, event propagating from child component


action click from my-child
click from my-child
action click from my-parent
click event from my-parent

Neat and this is the expected behaviour. Even though you call event.stopPropagation parent component, it's not doing anything.

twiddle 2 - Browser is handling the event, ie., <div onclick={{action 'test'}}>


action click from my-child
action click from my-parent
click from my-child
click event from my-parent

Here you can first its triggering action click from child to parent and then calling click handler for the corresponding component. In this case, if you call event.stopPropagation() in parent action click handler, then ember will not have an opportunity to call click handler of parent/child component.

This is what you are experiencing, to resolve you can move from <div onclick={{action 'clickMe'}}> to <div {{action 'clickMe'}}>.