Data binding 带有复选框和选中项的淘汰问题以及更改绑定

Data binding 带有复选框和选中项的淘汰问题以及更改绑定,data-binding,knockout.js,binding,onchange,checked,Data Binding,Knockout.js,Binding,Onchange,Checked,我刚刚发现了淘汰(3.0和3.1)和复选框的问题 问题是,复选框的更改事件绑定在不同浏览器中并不一致 请参见下面的代码 <table > <tr> <td > <input type="checkbox" data-bind='checked: CheckVal, event: { change: refresh }' /> </td> <td>Check Value in chec

我刚刚发现了淘汰(3.0和3.1)和复选框的问题

问题是,复选框的更改事件绑定在不同浏览器中并不一致

请参见下面的代码

<table >
  <tr> 
    <td >
      <input type="checkbox" data-bind='checked: CheckVal, event: { change: refresh }' />
    </td>
    <td>Check Value in checked binding: <span data-bind="text: CheckVal"></span> 
    </td>
  </tr>
  <tr>
      <td></td>
    <td>Check Value in changed event binding: <span data-bind="text: CheckValChanged"></span> 
    </td>
    </tr>        
</table>
在Firefox中,更改事件绑定发生在复选框值更改之后,因此在更改事件处理程序中,我们可以读取复选框的实际值(即,如果选中复选框,则绑定字段的值为true)

在所有其他浏览器中(我使用Chrome、IE 11、Opera和Safari进行了测试),更改事件绑定似乎是在实际更改绑定字段的值之前发生的(也就是说,如果选中复选框,则在更改处理程序中读取的值为false,如果未选中,则读取的值为true)

您可以在中看到演示的问题

问题不仅在于浏览器之间的行为不一致,而且对于大多数浏览器来说,这似乎是违反直觉的:事件是更改,而不是更改或更改前。在我看来,它应该在更改完成时触发是很自然的,因此绑定值应该反映当前选中的状态,而不是前一个状态

我在这里的问题,除了问题本身,是找到一个解决办法来处理这个问题。我的问题是,我需要根据复选框的值填充一个下拉列表,并且我选择在change event中执行此操作(鉴于发现的问题,现在这似乎是一个错误的选择)

我认为最好的方法是使用一个计算出的可观测值,我希望它能像预期的那样工作

我在等待bug的确认,也在等待最好地处理这种情况的建议


谢谢

您所能做的就是使用CheckVal observable的淘汰订阅,而不是使用change javascript事件

然后,每当CheckVal observable更改时,就会触发subscribe事件

您的MainViewModel将如下所示:

function MainViewModel() {
    var self = this;
    this.CheckVal = ko.observable(true);
    this.CheckValChanged = ko.observable(true);

    this.CheckVal.subscribe(function(value) { 
        self.CheckValChanged(value);
    });
}
然后,您的标签可以更改为:

<input type="checkbox" data-bind='checked: CheckVal' />


希望这能有所帮助。

您可以使用对CheckVal observable的淘汰订阅,而不是使用change javascript事件

然后,每当CheckVal observable更改时,就会触发subscribe事件

您的MainViewModel将如下所示:

function MainViewModel() {
    var self = this;
    this.CheckVal = ko.observable(true);
    this.CheckValChanged = ko.observable(true);

    this.CheckVal.subscribe(function(value) { 
        self.CheckValChanged(value);
    });
}
然后,您的标签可以更改为:

<input type="checkbox" data-bind='checked: CheckVal' />


希望这能有所帮助。

谢谢,但正如我所说的,我需要根据复选框的值填充一个下拉列表,我需要在checkbpx的更改事件中这样做。如果我保留change事件,它在不同浏览器中仍然具有不一致和错误的值。就我个人而言,我认为混合使用敲除和javascript事件更容易混淆。如果使用subscribe,则可以100%确保CheckVal值是最近的值。由于混合使用敲除可观察事件和javascript事件,您无法确定基于不同浏览器实现的事件顺序。感谢您的评论。我在几个应用程序中广泛使用更改事件来更新依赖控件(特别是当某些控件中的数据需要从服务器检索时,具体取决于其他控件的值),到目前为止,我从未遇到过任何问题。不应该将jquery事件与敲除一起使用,这是一种反模式。我不想成为那个追你的人。事实上,我不知道你为什么认为我在用jquery和knockout,因为我不是。我实际使用的是:1.将ui控件绑定到模型的可观察对象(例如下拉状态到可观察状态);2.将更改事件绑定到模型中的函数-例如stateChanged()。3.在stateChanged中,在ajax调用中使用StateObservable的值,从该州加载城市,然后我将其分配给cities observableArray。请澄清此模式有什么问题?谢谢,但正如我所说的,我需要根据复选框的值填充一个下拉列表,我需要在checkbpx的更改事件中这样做。如果我保留change事件,它在不同浏览器中仍然具有不一致和错误的值。就我个人而言,我认为混合使用敲除和javascript事件更容易混淆。如果使用subscribe,则可以100%确保CheckVal值是最近的值。由于混合使用敲除可观察事件和javascript事件,您无法确定基于不同浏览器实现的事件顺序。感谢您的评论。我在几个应用程序中广泛使用更改事件来更新依赖控件(特别是当某些控件中的数据需要从服务器检索时,具体取决于其他控件的值),到目前为止,我从未遇到过任何问题。不应该将jquery事件与敲除一起使用,这是一种反模式。我不想成为那个追你的人。事实上,我不知道你为什么认为我在用jquery和knockout,因为我不是。我实际使用的是:1.将ui控件绑定到模型的可观察对象(例如下拉状态到可观察状态);2.将更改事件绑定到模型中的函数-例如stateChanged()。3.在stateChanged中,在ajax调用中使用StateObservable的值,从该州加载城市,然后我将其分配给cities observableArray。请澄清这种模式有什么问题?