我刚刚发现了淘汰赛(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>
和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);
在Firefox中,更改事件绑定发生在复选框值更改后,因此在更改事件处理程序中,我们可以读取复选框的实际值(即,如果选中复选框,则绑定字段的值为= true )。
在所有其他浏览器中(我使用Chrome,IE 11,Opera和Safari测试过),更改事件绑定似乎在实际更改绑定字段的值之前发生(即,选中复选框,读取的值) in change handler是false,如果未选中,则read read为true)
您可以在http://jsfiddle.net/bzamfir/su6SW/2/
看到问题问题不仅在于浏览器中的行为不一致,而且对于大多数浏览器而言,这似乎是违反直觉的:事件是更改,而不是更改或 beforechange 。我很自然地认为它应该在更改完成时触发,因此绑定值应该反映当前检查的状态,而不是前一个状态。
除了问题本身,我的问题是找到一种解决方法来持续处理这个问题。我的问题是,我需要根据复选框的值填充下拉列表,我选择在更改事件中执行此操作(现在看起来是一个糟糕的选择,发现问题)。
我认为要采用的方法是使用计算的observable,我希望它能按预期工作。
我正在等待对错误的确认,以及建议以便最好地处理这种情况。
由于
答案 0 :(得分: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);
});
}
然后您的代码可以更改为:
<input type="checkbox" data-bind='checked: CheckVal' />
希望这会有所帮助。