Reputation: 11778
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: https://ember-twiddle.com/c9a014a0c19851596d5e1184c9967cbc
Is there a solution to bypass this problem?
Upvotes: 1
Views: 348
Reputation: 12872
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
output:
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'}}>
output:
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'}}>
.
Upvotes: 1
Reputation: 3368
I would oppose the suggestion made by @kumkanillam in his answer: " to resolve you can move from <div onclick={{action 'clickMe'}}>
to <div {{action 'clickMe'}}>
."
The first one (the original one you have used in your question) is the ember's closure action
in action :) It is much more powerful; such that you can return values from the parent component to the child component; because it is in fact a function where this
context is properly set by ember
underneath and you can detect unhandled actions eagerly. On the other hand what is suggested by @kumkanillam is generally named "action in element space". It is low level DOM event handling by Ember.
Please take a look at the following excellent article that explains why closure actions
rock! Regarding your question; what I would suggest is using closure actions
as much as possible and avoid DOM event action handling via moving the relevant code part to the action handling as @DanielKmak already mentioned in his comment. I personally prefer closure actions as much as possible and only rely on DOM event handlers (such as click
within box-content
and my-component
in your twiddle) when it is inevitable.
Upvotes: 2