更改“已检查”属性不会更改视图模型

时间:2016-06-18 12:47:01

标签: javascript knockout.js

我正在使用Knockout进行实验,这是JSFiddle

单选按钮具有与视图模型的enableMe属性的数据绑定。如果我单击单选按钮,它会更新enableMe属性,并且“已检查”数据绑定会被触发。

我要做的是,当我更改单选按钮的checked属性时(在按钮单击事件上)并查看视图模型是否更改。它不会改变。

为什么?需要知道在这种情况下淘汰是如何工作的。

var ViewModel = function() {   
    
    this.enableMe = ko.observable(false);    
};
 
var myVM = new ViewModel();
 
ko.applyBindings(myVM); 

function clickme() {
   //Changing the checked state does not change VM
   document.getElementById("myradio1").checked = true;
   //Changing the VM works
   //myVM.enableMe(true);
   
   alert("Alert Message OnClick");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
EnableMe: <input id="myradio1" type="radio" data-bind='checked: enableMe'/><br/>
Enable status: <span data-bind='text: enableMe'></span>
<br/>
<button id="button1" onclick="clickme();">Click To Disable</button>

1 个答案:

答案 0 :(得分:1)

几个问题:

  1. 使用KO时不要操纵DOM。请改为操作视图模型,让KO为您处理更新DOM。
  2. 您有一个单选按钮输入(没有value属性!)但似乎想要绑定布尔,这将require extra work
  3. 您使用onclick属性,其中还有click绑定处理程序。
  4. 如果您坚持忽略1并自己操纵DOM,请以KO收到更改通知的方式进行操作。因为你总是使用jQuery我建议使用它的API来触发输入上的事件。这是一个修复/解决问题2和3的演示:

    var ViewModel = function() {
      this.enableMe = ko.observable(false);
    };
     
    var myVM = new ViewModel();
     
    ko.applyBindings(myVM); 
    
    function clickme() {
      // This is NOT recommended! Check the second example.
      $("#mycheck1").trigger("click");
    }
    pre { font: 11px consolas; padding: 5px; background: #fafafa; border: 1px solid #ddd; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    EnableMe: <input value="true" id="mycheck1" type="checkbox" data-bind='checked: enableMe'/><br/>
    Enable status: <span data-bind='text: enableMe'></span>
    <br/>
    <button id="button1" data-bind="click: clickme">Click To Toggle</button>
    <hr>
    <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

    但是,你应该使用这样的方法:

    var ViewModel = function() {
      var self = this;
      
      self.enableMe = ko.observable(false);
      
      self.clickme = function() {
        self.enableMe(true);
      }
    };
     
    var myVM = new ViewModel(); 
    ko.applyBindings(myVM);
    pre { font: 11px consolas; padding: 5px; background: #fafafa; border: 1px solid #ddd; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
    
    EnableMe: <input value="true" id="mycheck1" type="checkbox" data-bind='checked: enableMe'/><br/>
    Enable status: <span data-bind='text: enableMe'></span>
    <br/>
    <button id="button1" data-bind="click: clickme">Click To Toggle</button>
    <hr>
    <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>