Deprecation Guide for Action helper and modifier
Scenario: action is passed a string
Before:
<button type="button" {{action "plusOne"}}>
Click Me
</button>
After:
<button type="button" {{on 'click' this.plusOne}}>
Click Me
</button>
or, if plusOne is passed in as an argument:
<button type="button" {{on 'click' @plusOne}}>
Click Me
</button>
If the plusOne action is in an actions object, it needs to move out:
For Glimmer components
Before:
import Component from '@glimmer/component';
export default class Demo extends Component {
actions = {
plusOne() {
/* ... */
}
}
}
After:
import Component from '@glimmer/component';
import { action } from '@ember/object';
export default class Demo extends Component {
@action
plusOne() {
/* ... */
}
}
or
For Classic Components with native classes
Before:
import Component from '@ember/component';
export default class Demo extends Component {
doMath() {
this.send('plusOne');
}
actions = {
plusOne() {
/* ... */
}
}
}
After:
import Component from '@ember/component';
import { action } from '@ember/object';
export default class Demo extends Component {
doMath() {
this.plusOne();
}
@action
plusOne() {
/* ... */
}
}
or
For Classic Components with EmberObject.extend
Before:
import Component from '@ember/component';
export default Component.extend({
actions: {
plusOne() {
/* ... */
}
}
})
After:
import Component from '@ember/component';
import { action } from '@ember/object';
export default Component.extend({
plusOne: action(function() {
/* ... */
}),
})
If (action) or {{action}} is passed a string, it's possible that the referenced method is declared on the caller, and not the immediate component -- that is, (action) and {{action}} bubble up the render tree from route templates -> controllers -> routes.
Note that @action is completely different from (action) or {{action}} (and is partly a motivator for deprecating (action) and {{action}}, to reduce ambiguity).
@action binds the this on the method to the instance of the class.
Scenario: action is passed a function reference
Before:
<SomeComponent @update={{action this.plusOne}} />
After
<SomeComponent @update={{this.plusOne}} />
Scenario: action is passed parameters
Before:
<SomeComponent @update={{action this.plus 1}} />
After:
<SomeComponent @update={{fn this.plus 1}} />
Scenario: action is used with mut
Before:
<SomeComponent @update={{action (mut @value.property}} />
After:
// parent.js
import Component from '@glimmer/component';
import { action } from '@ember/object';
export default class SomeComponent extends Component {
@action
handleUpdate(value) {
this.args.property = value;
}
}
{{! parent.hbs }}
<SomeComponent @update={{this.handleUpdate}} />
Related, Combining function arguments with action functions
For more background, read the RFC