程序化更改不会反映在knockout viewmodel中

时间:2012-10-22 09:20:38

标签: mvvm knockout.js

使用javascript更改复选框的状态与MVVM的精神不符。但我正在创建一个通用的JavaScript库,以便更好地查看标准控件,如复选框,单选按钮或选择框。 基于以下viewmodel:

function MyViewModel() {
  var self = this;

  self.ok = ko.observable();

};

var vm = new MyViewModel();
ko.applyBindings(vm);

但是当我以编程方式更改复选框的已检查状态时,我遇到了与淘汰相关的问题:

document.getElementById('chk').checked = true

更改不会出现在viewmodel的属性中。但是当我点击复选框时,一切正常。

查看http://jsfiddle.net/KWdZB/1/

有解决方法吗?

2 个答案:

答案 0 :(得分:5)

您的问题是ko订阅了checked binding内的click事件:

ko.utils.registerEventHandler(element, "click", updateHandler);

但更改checked属性不会触发点击事件,因此不会通知ko。

如果在属性更改后手动触发click事件,它可以正常工作......

我不知道如何使用纯javascript,但使用jQuery,你可以写:

$('#chk').attr('checked', true).triggerHandler('click')

您可以在此JSFiddle中对其进行测试。

答案 1 :(得分:1)

这是正常的,因为已检查的绑定处理程序不订阅已检查的更改事件,而是订阅click事件处理程序(您可以在已检查的绑定处理程序代码中查看源文件)。

如果您需要通过点击更改值,则必须使用ok可观察值。

有HTML

<div>
    <input type="checkbox" id="chk" data-bind="checked: ok"/><br>
    <input type="button" id="btnCheck" value="Check" data-bind="click: Check"/>&nbsp;&nbsp;    
    <input type="button" id="btnUnCheck" value="Uncheck" data-bind="click:Uncheck"/> 
</div>
<div>
    Value: <span data-bind="text: ok"></span>    
</div>

和javascript:

function MyViewModel() {
    var self = this;

    self.ok = ko.observable();

    self.Check = function(){
      self.ok(true);      
    }

    self.Uncheck = function(){
        self.ok(false);            
    }
};

vm = new MyViewModel();
ko.applyBindings(vm);

您可以在此fiddle中看到它。