【问题标题】:How to render an array as a list of radio buttons?如何将数组呈现为单选按钮列表?
【发布时间】:2012-02-13 18:53:33
【问题描述】:

我想遍历我在 Javascript 中定义的数组并呈现单选按钮列表。我的代码目前不工作,如下(也在jsfiddle):

<div data-bind="foreach: options" >
    <div>
        <input type="radio" name="optionsGroup" data-bind="checked: selected" />
        <span data-bind="text: label"></span>
     </div>    
</div>
var optionsList = [
    {"value": "a","label": "apple"},
    {"value": "b","label": "banana"},
    {"value": "c","label": "carrot"}
];
function viewModel() {
    var self = this;
    self.options = optionsList;
    self.selected = ko.observable("a");
    self.selected.subscribe(function(newValue) {
        alert("new value is " + newValue);
    });
}
ko.applyBindings(new viewModel());

如果我的数组是 html 的一部分,那么它可以正常工作,请参阅此(或 jsfiddle):

<div>
    <input type="radio" name="optionsGroup" value="a" data-bind="checked: selected"     />Apple
</div>
<div>
    <input type="radio" name="optionsGroup" value="b" data-bind="checked: selected" />Banana
</div>
<div>
     <input type="radio" name="optionsGroup" value="c" data-bind="checked: selected" />Carrot
</div>
<div data-bind="text: selected">
</div>
function viewModel() {
    var self = this;
    self.selected = ko.observable("a");
    self.selected.subscribe(function(newValue) {
        alert("new value is " + newValue);
    });
}    
ko.applyBindings(new viewModel());

我通过在我的 javascript 中生成所有 html 并使用复选框来实现它,但我很难使用 foreach 迭代器生成一组单选按钮。

有人得到像我第一个工作的例子吗?

【问题讨论】:

  • 当然你可以想出一个信息更丰富的标题。
  • 值得注意的是,您的 viewModel 中不需要 var self = this。删除该行并将所有selfs 更改为this。没有范围也没关系。

标签: arrays foreach knockout.js radio checked


【解决方案1】:

这是执行此操作的一种方法。请注意,attr 绑定应位于 checked 绑定之前。

var optionsList = [
    {"value": "a", "label": "apple"},
    {"value": "b", "label": "banana"},
    {"value": "c", "label": "carrot"}
];

function viewModel() {
    this.options = optionsList;
    this.selected = ko.observable("a");
}

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

<h3>Fruits</h3>
<div data-bind="foreach: options" >
  <label>
    <input type="radio"
           name="optionsGroup" 
           data-bind="attr: {value: value}, checked: $root.selected" />
    <span data-bind="text: label"></span>
  </label>    
</div>

<h3>Selected value:</h3>
<pre data-bind="text: ko.toJSON($root.selected)"></pre>

【讨论】:

  • 我的问题是 attr 绑定在检查之前没有出现。有道理,但不会马上显现出来。
  • Fiddle of above answer in context(只是为了好玩)。
  • 在最近的 Knockout 版本中,$root 已成为 $parent
【解决方案2】:

您的代码出现此错误:

消息:ReferenceError: selected is not defined;

绑定值:选中:选中

您在视图模型级别定义了 selected,但您在 foreach 内部引用它,因此 Knockout.js 正在选项级别查找它。

变化:

<div><input type="radio" name="optionsGroup" data-bind="checked: selected" />

到:

<div><input type="radio" name="optionsGroup" data-bind="checked: $root.selected" />

$root.selected 将在视图模型级别查找 selected 属性。

HERE是修改后的代码。

有关伪变量(如$root)的更多信息,请参阅3. Access to parent binding contexts

【讨论】:

    【解决方案3】:

    为了能够拥有整个对象,最好使用 checkedValue 而不是 attr: {value} 这样:

    Fruits
    <div data-bind="foreach: options" >
        <div><input type="radio" name="optionsGroup" data-bind="checkedValue: $data, checked: $root.selected" />
        <span data-bind="text: label"></span></div>    
    </div>
    

    【讨论】:

      【解决方案4】:

      你的代码是有效的。只需在您的 jsfiddle 中包含 knockout.js 并将文档设置为“onDomready”。

      【讨论】:

        猜你喜欢
        • 2017-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-24
        • 2022-12-22
        • 2012-05-01
        • 2019-12-18
        相关资源
        最近更新 更多