@action Decorator

Bind this and Make a Method Template-Safe

@action Decorator

The action decorator binds this to the component and is the canonical way to expose methods to templates.

4 min read Level 2/5 #ember#actions#octane
What you'll learn
  • Decorate methods with the action decorator
  • Pass them to the template via the `this.method` reference
  • Use them with the on modifier as event handlers

In Octane, the recommended way to write event handlers and template-callable methods is @action. It does two things — binds this to the component, and marks the method as safely passable as a value.

A Handler

import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';

export default class SaveForm extends Component {
  @tracked draft = '';

  @action
  save() {
    this.args.onSave(this.draft);
    this.draft = '';
  }
}
<form {{on "submit" this.save}}>
  <input value={{this.draft}} />
  <button type="submit">Save</button>
</form>

Why The Decorator

Without @action, passing this.save would lose its binding when invoked by the DOM. @action auto-binds, so you never need this.save = this.save.bind(this) in a constructor.

Passing Args

To curry arguments at the template, combine with the fn helper:

{{#each @items as |item|}}
  <button {{on "click" (fn this.delete item.id)}}>Delete</button>
{{/each}}

The handler receives the curried args first, then the DOM event:

@action
delete(id, event) {
  event.preventDefault();
  this.args.onDelete(id);
}
The on Modifier →