Ember Actions by Example

Ember’s actions are a powerful and usually straight-forward mechanism for handling events within an application. However, some cases can be a bit perplexing unless you’ve dealt with them before and wrestled with the details. Here are a few brief points and examples to help clarify Ember’s action bubbling behavior in a few of those less obvious cases.

Current Active Leaf Route

My primary reference for Ember’s action behavior is their own guide regarding actions. Within that guide is a sentence that provides a key piece of information that’s easy to miss (emphasis mine):

If the controller does not implement a method with the same name as the action in its actions object, the action will be sent to the router, where the __currently active leaf route__ will be given a chance to handle the action.

Woah! This means that an action fired in a template for a controller higher in the hierarchy can trigger an action handler on a lower route! I must confess I haven’t needed to use this pattern an an application yet, but it’s good to know. See the diagram below for an illustration.

currently_active_leaf_route

In this example, the bubbling of the action does not go directly from the BooksController to the BooksRoute, but instead gives the BookRoute the option to handle it first. A JS Bin example is available at the link below to illustrate in code. First, try clicking the button when the BookRoute is the active leaf route, and then when the BooksRoute is the active leaf route to see the different alert messages.

Bubbling from a View

Views don’t automatically bubble actions up to their controller, however they can send actions more directly using:

@get('controller').send('actionName')

When sending the action to the controller, the bubbling follows the same path as the above “currently active leaf route” path.

bubbling_from_a_view

If the view did nothing to re-fire the action, the bubbling would stop before it got to the controller. Needing to re-fire the action is a good opportunity to map a UI action like “click” into something more meaningful to the domain of your application.

Try the JS Bin—there will be two alerts shown, one for the view and one for either the Book or Books controller (depending on which of them are active).

Within a Component

One of the things I appreciate most about Ember’s components is the boundary it creates between a reusable piece of code and its users. It makes it far more difficult to entangle a component with a specific controller. It also makes it necessary to map actions between a component’s domain and a controller’s interface.

Actions do not bubble out of a component.

Ember’s documentation for passing actions from a component to your application is excellent, so I won’t dig into much detail here aside from this diagram and a JS Bin example.

This diagram shows an event “click” being fired from the BooksButton component’s template, and then being handled by the BooksButtonComponent itself. Then, the BooksButtonComponents calls sendAction() to trigger its default action, which is mapped to “read” in the Books template’s inclusion of the component. The “read” event will then bubble up the stack as shown.

bubbling_from_a_component

See the JS Bin example for more detail about how actions work in the context of an Ember component.

What Action “Gotchas” Have You Seen?

Those are the three “tricky” cases I’ve noticed so far with Ember’s actions, but I’d love to hear what others have found. Please share in the comments!

 
Conversation
  • Dennis says:

    Well, another case is sending actions from nested components, which gets ugly and cumbersome pretty fast because the actions don’t bubble to parents. Hope they make this easier in Ember 2.0

  • Comments are closed.