单击另一个单选按钮时更改单选按钮的值

时间:2016-06-22 20:07:55

标签: knockout.js

我需要创建一个选项列表,当我在一个选项中单击时,我使用" X"更改所有其他选项的值。它工作正常,但我选择的选项不会保持选中状态。有谁知道出了什么问题?



var data = [{
  name: "CheckBox1",
  status: " "
}, {
  name: "CheckBox2",
  status: "X"
}, {
  name: "CheckBox3",
  status: "X"
}];

var ViewModel = function() {
  var self = this;
  self.list = ko.mapping.fromJS(data);

  self.change = function(data) {
    for (i = 0; i < self.list().length; i++)
      self.list()[i].status("X");
    data.status(" ");
    return true;

  }

}

ko.applyBindings(new ViewModel(data));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>


<!--ko foreach: $root.list-->
<!-- ko with: $data -->
<label data-bind="text: name"></label>
<input type="radio" data-bind="checkedValue: status() === ' ', click:$root.change" />
<!--/ko-->
<!--/ko-->

<!--ko foreach: $root.list-->
<!-- ko with: $data -->
<p data-bind="text: name"></p>
<p data-bind="text: status"></p>

<!--/ko-->
<!--/ko-->
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

如果重做绑定单选按钮的方式(如淘汰网站上),则无需手动更新选中的值。由于检查的绑定是布尔表达式,因此检查的绑定实际上是单向绑定而不是双向绑定。数据将驱动接口,但接口不会驱动数据。这就是您必须手动“检查”单击功能中的框的原因。也就是说,为了最低限度地修改你的例子,我能够通过一些调整来实现它。

编辑:现在意识到虽然这使得样本“正常”,但它只是打破了检查的绑定。所以...如果您要更新数据,它将无法驱动控件。

删除已检查绑定中的调用括号。这是数据更新后单选按钮未更新的部分原因。

<input type="radio" name="optradio" data-bind="checked: status == ' ', click: $root.change" />

修改控件绑定到的集合的值,而不是传入的数据参数。如果不直接修改集合,则不会更新控件引用的对象。它基本上就像是通过参考物传递价值而传递的。

for (i = 0; i < self.list().length; i++){
    if(self.list()[i].name() == data.name()){
    self.list()[i].status(' ');
  }
  else{
    self.list()[i].status('X')
  }
}

var data = [{
  name: "CheckBox1",
  status: " "
}, {
  name: "CheckBox2",
  status: "X"
}, {
  name: "CheckBox3",
  status: "X"
}];

var ViewModel = function() {
  var self = this;
  self.list = ko.mapping.fromJS(data);

  self.change = function(data) {
    for (i = 0; i < self.list().length; i++){
    	if(self.list()[i].name() == data.name()){
      	self.list()[i].status(' ');
      }
      else{
      	self.list()[i].status('X')
      }
    }
    for (i = 0; i < self.list().length; i++)
      alert(self.list()[i].status());

    return true;
  }

}

ko.applyBindings(new ViewModel(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>


<!--ko foreach: $root.list-->
<!-- ko with: $data -->
<label data-bind="text: name"></label>
<input type="radio" name="optradio" data-bind="checked: status === ' ', click:$root.change" />
<!--/ko-->
<!--/ko-->

答案 1 :(得分:1)

https://jsfiddle.net/ptk2jf8v/20/

<input type="radio" name="optradio" data-bind="checkedValue: status() === ' ', click:$root.change,value:status" />

并从click处理程序返回true将执行操作

来自:http://knockoutjs.com/documentation/checked-binding.html

  

如果您的绑定还包含checkedValue,则定义该值   由checked绑定使用而不是元素的value属性。   如果您希望该值不是a,则此选项非常有用   字符串(例如整数或对象),或者您想要设置值   动态。

在您的情况下,当状态为空时,您将标记为已选中。

此外,点击事件会搞乱单选按钮上发生的默认操作。

来自knockout js radio button click event reset selection

  

默认情况下,Knockout会阻止点击事件   默认操作

因此,从click事件返回true将有助于冒泡。