Reputation: 83
I have a checkbox like this:
{{input type="checkbox" checked=property}}
When I click the checkbox the property is changed. Now I like to call a function to persist the property. But what is the best way to do this?
I could bind an action to input oder click.
{{input ... input=(action "actionName") click=(action "actionName")}}
This doesn't work because the property has still the old value when the action is called.
Extending the class Checkbox:
import Checkbox from '@ember/component/checkbox';
Checkbox.reopen({
onChange: null,
change() {
this._super();
if (this.onChange) this.onChange();
}
});
...
{{input ... onChange=(action "actionName")}}
But the function change is not documented, even though the source code indicates that it is feasable to override.
I could bind an action to didUpdate or didUpdateAttrs, but the action is called twice. In my case this wouldn't be a problem, because the property is part of a model, so I could call model.get('hasDirtyAttributes')
in the action.
[Update] In my test case the action was called twice but in my real code it is only called once, so this seems to be the best solution?[/Update]
So what is the proper ember.js-way to do this?
Upvotes: 0
Views: 840
Reputation: 3052
Have a look at my ember-twiddle example.
I would suggest using input
helper,
({input type="checkbox" click=(action "setProperty") checked=my_property}}
toggle the property inside the action
setProperty() {
// toggle the property on click
this.toggleProperty("my_property");
console.log(this.get('my_property')); // returns true or false based on the checked value
.. // do whatever stuff you want
}
If your at the most recent version of ember 3.9
, have a look at this
Upvotes: 0
Reputation: 8724
I personally prefer one way binding with checkboxes. I use the native input
like so:
<input type="checkbox" checked={{myValue}} onclick={{action (mut myValue) value="target.checked"}}>
Check this twiddle to see it live in action. This is the easiest, non-library approach for 1-way bound checkboxes, which I would argue is the "ember-way" as of 2.x (although I do know people that still like and use the 2-way bound input which more requires observers in cases like what you described as far as I can tell).
In one of my projects, I use ember-paper which uses a nicely displayed checkbox without input
and I believe the correct aria-bindings for a11y. They leverage click
to invoke onChange
click() {
if (!this.get('disabled')) {
invokeAction(this, 'onChange', !this.get('value'));
}
// Prevent bubbling, if specified. If undefined, the event will bubble.
return this.get('bubbles');
}
such that you can use with the following api
{{#paper-checkbox value=value1 onChange=(action (mut value1))}}
A checkbox: {{value1}}
{{/paper-checkbox}}
You can see the example and how the template and component js are implemented for inspiration should you want a better looking checkbox than native
Upvotes: 3