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