Knockout + Radiobuttons - 在取消选中时将值切换回'false'

Ove*_*lew 1 knockout.js

我有一个Knockout应用程序,我有多个布尔属性,只有1个可以true.(而不是一个底层属性,每个radiobutton是一个不同的值).

当我选择一个单选按钮时,observable将正确更新为单选按钮checkedValue.当我取消选择它时,值仍然存在.我有什么方法可以将此设置为可观察到的false

我的JS小提琴示例:http://jsfiddle.net/9mu8e/

我有点担心设置一个中间值,而.subscribe()来整理所有值.(分散的布尔值是我们发送的REST接口的一个特性).

更新:我添加了"添加新"按钮以将列表显示为动态,并且可能包含重复值(因此无法跟踪文本属性或理论数据库ID).jsFiddle链接已更新.

我的例子:

视图:

<div>Current item: 
    <input type="radio" name="group" data-bind="checked: isMostTerrible, checkedValue: true" />
    <span data-bind="text: isMostTerrible"></span>
</div>

<ul data-bind="foreach: itemsList">
    <li>
        <span data-bind="text: name"></span>
        <input type="radio" name="group" data-bind="checked: isMostTerrible, checkedValue: true" />
        <span data-bind="text: isMostTerrible"></span>
    </li>
</ul>

<button data-bind="click: onAddNewItem">Add new</button>
Run Code Online (Sandbox Code Playgroud)

查看型号:

var item = function(name, dbId) {


var self = this;

    self.dbId = ko.observable(dbId);
    self.name = ko.observable(name);
    self.isMostTerrible = ko.observable(false);
}

var itemList = [
    new item("Taxes", 1),
    new item("Death", 2)
]

var viewModel = function() {
  var self = this;

    self.isMostTerrible = ko.observable(true);
    self.itemsList = ko.observableArray(itemList);

    self.onAddNewItem = function() {
        // Note - Adding a new item doesn't add a DB ID.
        // (Theoretically occurs on save)
        self.itemsList.push(new item("New item"));
    }
};

ko.applyBindings(viewModel);
Run Code Online (Sandbox Code Playgroud)

Mic*_*est 8

一个问题是Knockout的checked绑定根本不适合你尝试使用它的方式.它意味着要设置一个可观察到的单个observable,每个按钮都有一个唯一的值.

另一个问题是,当取消选择单选按钮时,浏览器不提供通知.(请参阅单选按钮的OnChange事件处理程序(INPUT type ="radio")不能作为一个值工作).因此,侦听change事件的简单绑定将不起作用.

尽管如此,使用自定义绑定仍然可以实现.我在下面包含的那个使用了一个observable来跟踪当前选择的单选按钮,以便它可以相应地更新模型值.

ko.bindingHandlers.radioChecked = (function() {
    var groupObservables = {};
    return {
        init: function(element, valueAccessor) {
            var name = element.name,
                groupObservable = groupObservables[name] || (groupObservables[name] = ko.observable());

            ko.utils.registerEventHandler(element, 'click', function() {
                valueAccessor()(element.checked);
            });
            var s1 = ko.computed(function() {
                if (valueAccessor()()) {
                    element.checked = true;
                    groupObservable(element);
                }
            });
            var s2 = groupObservable.subscribe(function() {
                valueAccessor()(element.checked);
            });
            ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
                s1.dispose();
                s2.dispose();
            });
        }
    };
})();
Run Code Online (Sandbox Code Playgroud)

小提琴:http://jsfiddle.net/mbest/3dy3s/