【问题标题】:knockout issue with checkbox and checked and change bindings复选框的剔除问题,选中并更改绑定
【发布时间】:2014-07-08 13:57:47
【问题描述】:

我刚刚发现了敲除(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,如果未选中,则读取的值为 true)

您可以在http://jsfiddle.net/bzamfir/su6SW/2/ 看到演示的问题

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

除了问题本身之外,我的问题是找到一种解决方法来始终如一地处理这个问题。我的问题是,我需要根据复选框的值填充一个下拉列表,并且我选择在更改事件中执行此操作(现在这似乎是一个糟糕的选择,因为发现了问题)。

我认为要走的路是使用计算出的 observable,我希望它可以按预期工作。

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

谢谢

【问题讨论】:

    标签: data-binding knockout.js binding onchange checked


    【解决方案1】:

    您可以做的是使用对 CheckVal 可观察对象的淘汰订阅,而不是使用更改 javascript 事件。

    然后每次 CheckVal 可观察值发生变化时都会触发 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 的更改事件中执行此操作。如果我保留更改事件,它仍然具有跨浏览器的不一致和错误的值。见jsfiddle.net/bzamfir/su6SW/7
    • 我个人认为使用像这样的淘汰赛和 javascript 事件的混合会更令人困惑。如果您使用订阅,您可以 100% 确定 CheckVal 值是最新的。混合使用敲除 observables 和 javascript 事件,您无法确定基于不同浏览器实现的事件顺序。
    • 感谢您的评论。我在几个应用程序中广泛使用了 change 事件来更新依赖控件(尤其是当某些控件中的数据需要从服务器检索时,取决于其他控件的值),到目前为止从未遇到任何问题。
    • 你不应该使用带有敲除的 jquery 事件,它是一种反模式。我不想成为追随你的人。
    • 实际上,我不确定您为什么认为我使用带有淘汰赛的 jquery,因为我不是。我实际使用的是: 1.将 ui 控件绑定到模型的可观察对象,例如下拉状态到状态可观察); 2.将更改事件绑定到模型中的函数 - 例如状态改变()。 3. 在 stateChanged 中,使用 ajax 调用中的 State observable 的值,从 state 中加载城市,然后我将其分配给 Cities observableArray。请澄清这种模式有什么问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 2014-02-14
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多