✅ The extends: 'recommended'
property in a configuration file enables this rule.
Ember's built-in form components use two-way data binding, where the property passed as @value
or @checked
is mutated by user interaction. This goes against the Data Down Actions Up principle, goes against Glimmer Components’ intention to have immutable arguments, and is discouraged by the Ember Core team.
This rule forbids the following:
Many forms may be simplified by switching to a light one-way data approach.
For example – vanilla JavaScript has everything we need to handle form data, de-sync it from our source data and collect all user input in a single object.
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class MyComponent extends Component {
@tracked userInput = {};
@action
handleInput(event) {
const formData = new FormData(event.currentTarget);
this.userInput = Object.fromEntries(formData.entries());
}
}
Another option would is to "control" the field's value by replacing the built-in form component with a native HTML element and binding an event listener to handle user input.
In the following example the initial value of a field is controlled by a local tracked property, which is updated by an event listener.
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
export default class MyComponent extends Component {
@tracked name;
@action
updateName(event) {
this.name = event.target.value;
}
}
You may consider composing the set helper with the pick helper to avoid creating an action within a component class.