I'm using Ember v2.5.1 and Ember data v2.6.2 and I have a series of nested components to render a hierarchical tree of categories. There is a closure action in the lowest level component categories-tree-node
, which calls the toggleAddCategory
function in the actions of the categories-select
component and passes up the relevant category object.
It works as expected in Safari, but for some reason the checked state is passed through inverted in Chrome and FF. The strange thing is that the checked state binding of the value itself renders correctly elsewhere in the template when the checkboxes are changed.
I have created a demo here , if you try checking/unchecking the boxes in Chrome/FF vs Safari you should see the issue. Is there a prefered way of handling this type of action binding with checkbox checked states? I have read that using Observers is considered an anti-pattern in Ember 2 and above, also when I tried this it did not work for the child categories.
Ok so your twiddle shows that the state is unchanged in Chrome but changed in Safari.
This is most likely a bug with jQuery in Safari because Ember.CheckBox sets checked
using the jQuery prop method:
change() {
set(this, 'checked', this.$().prop('checked'));
}
A workaround solution would be to use the checkbox as an angle-bracket component ( which have one-way bindings by default ) to ensure the checked
binding is not changed by the input
component and instead use the passed in closure action to manually toggle the checked state yourself.
This also goes along with the Ember recommended best practice for setting parent properties from components using the Data Down - Actions Up pattern.
Note: You might want to use the onchange
event rather than onclick
.
Child components/categories-tree-node.hbs
<input type="checkbox"
checked={{category.checked}} <!-- checked is just passed from above, not set within the component -->
onchange={{action toggle category}} <!-- onchange calls the passed in action which toggles checked -->
id={{concat elementId '-' category.slug}}
>
...
Parent components/categories-select.js
export default Ember.Component.extend({
// ...
actions: {
toggleAddCategory(category) {
category.toggleProperty('checked'); // toggle the property yourself
// ...
}
}
});
If your parent action only does the toggle and nothing else, you probably don't need it and can do the toggling right inside the components/categories-tree-node.hbs
using the mut helper:
<input type="checkbox"
checked={{category.checked}} <!-- checked is just passed from above, not set within the component -->
onchange={{action (mut category.checked) value="target.checked"}} <!-- onchange automatically sets category.checked -->
id={{concat elementId '-' category.slug}}
>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.