简体   繁体   English

已检查状态的复选框绑定在Chrome中反转

[英]Checkbox binding of checked state inverted in Chrome

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. 我正在使用Ember v2.5.1和Ember数据v2.6.2,我有一系列嵌套组件来呈现类别的分层树。 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. 最低级别组件categories-tree-node存在关闭操作,该categories-tree-nodecategories-select组件的操作中调用toggleAddCategory函数并传递相关类别对象。

It works as expected in Safari, but for some reason the checked state is passed through inverted in Chrome and FF. 它在Safari中按预期工作,但由于某种原因,检查状态在Chrome和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. 我在这里创建了一个演示 ,如果您尝试检查/取消选中Chrome / FF vs Safari中的框,您应该会看到问题。 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. 我已经读到使用Observers被认为是Ember 2及以上版本中的反模式,当我尝试这个时它也不适用于子类别。

Ok so your twiddle shows that the state is unchanged in Chrome but changed in Safari. 好的,所以你的旋转显示Chrome中的状态没有变化,但在Safari中更改了。

This is most likely a bug with jQuery in Safari because Ember.CheckBox sets checked using the jQuery prop method: 这很可能是Safari中jQuery的一个错误,因为Ember.CheckBox使用jQuery prop方法进行了checked

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. 解决方法是使用复选框作为角括号组件( 默认情况下具有单向绑定 ),以确保input组件不会更改checked绑定,而是使用传入的闭包操作手动切换选中的陈述自己。

This also goes along with the Ember recommended best practice for setting parent properties from components using the Data Down - Actions Up pattern. 这也与Ember建议的最佳实践一起使用Data Down - Actions Up模式从组件设置父属性。

Note: You might want to use the onchange event rather than onclick . 注意: 您可能希望使用onchange事件而不是onclick

Child components/categories-tree-node.hbs 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 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: 如果您的父操作只执行切换而没有其他操作,您可能不需要它,并且可以使用mut帮助程序在components/categories-tree-node.hbs内部切换:

<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}}
>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM