带有复选框的敲除问题并检查并更改绑定

bza*_*fir 0 data-binding binding onchange checked knockout.js

我刚刚发现了淘汰赛(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>
Run Code Online (Sandbox Code Playgroud)

和javascript

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

    this.refresh = function() {
        self.CheckValChanged(self.CheckVal());
    }
}

viewModel = new MainViewModel();
ko.applyBindings(viewModel);
Run Code Online (Sandbox Code Playgroud)

在Firefox中,更改事件绑定发生在复选框值更改后,因此在更改事件处理程序中,我们可以读取复选框的实际值(即,如果选中复选框,则绑定字段的值为value = true).

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

你可以在http://jsfiddle.net/bzamfir/su6SW/2/看到这个问题.

问题不仅在于浏览器中的行为不一致,而且对于大多数浏览器而言,这似乎是违反直觉的:事件是变化,而不是变化变化之前.我很自然地认为它应该在更改完成时触发,因此绑定值应该反映当前检查的状态,而不是前一个状态.

除了问题本身,我的问题是找到一种解决方法来持续处理这个问题.我的问题是,我需要根据复选框的值填充下拉列表,我选择在更改事件中执行此操作(现在看来这是一个糟糕的选择,发现问题).

我认为要走的路是使用一个计算的observable,我希望它能按预期工作.

我正在等待错误的确认,以及最佳处理这种情况的建议.

谢谢

小智 5

你可以做的是使用对CheckVal observable的淘汰订阅,而不是使用更改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);
    });
}
Run Code Online (Sandbox Code Playgroud)

然后您的标记可以更改为:

<input type="checkbox" data-bind='checked: CheckVal' />
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.