【问题标题】:RadioButtonList with Knockout带有淘汰赛的 RadioButtonList
【发布时间】:2012-08-08 05:56:33
【问题描述】:

我需要一个带有一堆类似于 CheckBoxList 的开/关选项的 RadioButtonList。我需要将它转换为每个选项的开/关,但 Knockout 将一组单选按钮解析为一个值。有什么建议吗?

示例:http://jsfiddle.net/DPnBE/2/

【问题讨论】:

  • 公民被捕。这实际上是对单选按钮隐喻的误用。任何时候都应该只有一个单选按钮处于活动状态——这些选项是相互排斥的,就像老式汽车收音机一样。您不能同时收听多个电台,对吗? GUI 约定成功的原因在于它们的传统性。
  • “公民被捕”这很有趣。单选按钮 UI 不受影响,只是基础数据。对于用户来说,它的外观和工作方式仍然符合预期。看看答案上的示例 jsFiddle。

标签: knockout.js radio radio-group


【解决方案1】:

我发现匹配单选按钮和复选框的最佳方法是将 checked 绑定设置为选定值的数组。

不过,要实现这一点,每个单选按钮/复选框都需要一个值,然后该值与所选值数组中的值相匹配。

根据您的小提琴,我想出了以下 HTML:

<div id="two">
    <div data-bind="foreach: items">
        <label>
            <input name="items" 
                   type="radio" 
                   name="radioItems" 
                   data-bind="value: name, 
                              checked: $root.selectedItemNames" />
            <span data-bind="text:name"></span>
        </label><br/>
    </div><div data-bind="text: ko.toJSON($root)"></div>
</div>

下面是使它工作的 JavaScript:

var viewModel2 = {
    "items": [
        {
            "name": "one",
            "selected": ko.observable(false)
        },
        {
            "name": "two",
            "selected": ko.observable(true)
        },
        {
            "name": "three",
            "selected": ko.observable(false)
        }
    ]
};

viewModel2.selectedItemNames = ko.computed(function(){
    var selectedNames = [];
    ko.utils.arrayForEach(viewModel2.items, function(item) {
        if(item.selected()){
            selectedNames.push(item.name);
        }
    });
    return selectedNames;
});

ko.applyBindings(viewModel2, document.getElementById('two'));​

最后,这是我的 fork fiddle 的链接,您可以在其中查看此代码的运行情况,以及以类似方式工作的复选框的重新设计版本:

如果您有任何问题,请告诉我。

更新: http://jsfiddle.net/jimmym715/h2e9j/

【讨论】:

  • 抱歉,我已经用我发布时要添加的链接更新了我的答案......再次,如果您有任何问题,请告诉我
  • 它不工作。 "除非您指定 'write' 选项,否则无法将值写入dependentObservable。"
  • hmmm... 我太专注于获得正确的值而没有足够的进一步选择:-\ 我只是又运行了一次,但我遇到的问题是固有的Knockout 本身,特别是,当复选框组中的复选框被选中/取消选中时,Knockout 正在向/从 Knockout 自己的状态变量数组添加/删除绑定到该复选框的项目,以管理该复选框组,并且该数组管理选定的 价值观。这适用于字符串,但它似乎不适用于对象。也就是说,我以前做过类似的事情。
  • 不过,在我的工作版本中,我有一个选定的美国州缩写列表作为observableArray,以及一个绑定到 UsStateOption 对象列表的多选列表框(abbr +名称作为属性)。此外,我为 selectedStates 创建了一个依赖的 observable (ko.computed),它有一个 read 函数,它从所有 UsStateOptions 列表中创建了一个 UsStateOption 对象数组(以便对象完全匹配)和一个 write 函数读取传入该函数的值数组中的选定状态并更新可观察的状态缩写数组。
  • jsfiddle 示例不工作。复选框列表和单选按钮列表都不是。复选框列表甚至会抛出异常。
【解决方案2】:

我做了一个自定义绑定。您可以通过将先前选择的项目存储在某处来摆脱 for 循环。然后你只需要选择和取消选择 2 个项目。

更新示例: http://jsfiddle.net/DPnBE/5/

ko.bindingHandlers.radioCheck = {
    init: function(element, valueAccessor) {
        //initalize checked value of element
        element.checked = valueAccessor()();

        //attach event to handle changes
        $(element).change(function(e) {
            var item = ko.dataFor(element);
            var items = ko.contextFor(element).$parent.items;
            for (var i = 0; i < items.length; i++) {
                //set selected() for all items
                //true for the checked element, false for the rest
                items[i].selected(items[i] == item);                
            }
        });        
    }
};

【讨论】:

    猜你喜欢
    • 2018-05-26
    • 1970-01-01
    • 2018-08-01
    • 2012-08-05
    • 2013-05-15
    • 2019-02-15
    • 2013-03-22
    • 2013-03-09
    • 2014-05-07
    相关资源
    最近更新 更多