There are two kinds of {{action}}
in Ember Classic: the modifier, and the helper—and both of them had their own special sauce. Octane simplifies this by providing the {{on}}
modifier and the {{fn}}
helper, each of which does just one thing.
{{on}}
In Ember Classic, the {{action}}
modifier can be applied to a component to bind its event handling, handling click
events by default, and it looks up methods in the actions
object on a backing class by string name:
<button type="button" {{action "doIt" on="doubleClick"}}>Click me twice!</button>
There are three changes for using {{on}}
instead:
click
events on a <div>
—don't do that!).actions
object is no longer used; instead, any method on the backing class may be used—so simply doing this.doIt
is appropriate.dblclick
instead of doubleClick
.Putting them all together, and we would rewrite the example above like this:
<button type="button" {{on "dblclick" this.doIt}}>Click me twice!</button>
<aside>
💡 Note: the action on the backing class should always be decorated with @action
to make sure it's safe to call and pass around! The details: @action
binds the context of the method: it keeps the this
the same no matter what—like using the bind
method.
</aside>
{{fn}}
In Ember Classic, the {{action}}
helper does two things: partial application of arguments, and looking up methods in the actions
object on a backing class. So for example, when passing an action to a component:
<FancyButton @onClick={{action "doIt" 1}} />
Then in the body of FancyButton
, we might have something like this:
<button type="button" {{on "click" (action @onClick "two")}}>click!</button>
Here, the doIt
method on the backing class would receive both 1
and "two"
as arguments.
This ability to partially apply arguments is very useful, so we now do that with {{fn}}
. As noted above in the discussion of {{on}}
, we no longer need the ability to look up values in the actions
object!
We would rewrite the above example like this:
<FancyButton @onClick={{fn this.doIt 1}} />