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

时间:2016-11-02 14:55:06

标签: javascript ember.js

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

它在Safari中按预期工作,但由于某种原因,检查状态在Chrome和FF中反转。奇怪的是,当复选框被更改时,值本身的已检查状态绑定会在模板中的其他位置正确呈现。

我创建了demo here,如果您尝试选中/取消选中Chrome / FF vs Safari中的框,您应该会看到问题。是否有一种优先处理这种类型的动作绑定与复选框检查状态的方法?我已经读到使用Observers被认为是Ember 2及以上版本中的反模式,当我尝试这个时它也不适用于子类别。

1 个答案:

答案 0 :(得分:0)

好的,所以你的旋律显示Chrome中的状态没有变化,但在Safari中有所改变。

这很可能是Safari中jQuery的一个错误,因为Ember.CheckBox sets checked使用了jQuery prop方法:

change() {
  set(this, 'checked', this.$().prop('checked'));
}

解决方法是将复选框用作尖括号组件(which have one-way bindings by default),以确保checked组件不会更改input绑定,而是使用传递在关闭动作中自己手动切换已检查状态。

这也符合Ember推荐的使用Data Down - Actions Up模式从组件设置父属性的最佳实践。

注意:You might want to use the onchange event rather than onclick

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

...

家长 components/categories-select.js

export default Ember.Component.extend({
  // ...

  actions: {

    toggleAddCategory(category) {
      category.toggleProperty('checked'); // toggle the property yourself

      // ...  
    }

  }
});

如果您的父操作只执行切换而没有其他操作,您可能不需要它,并且可以使用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}}
>