将 checkedValue 绑定与单选按钮一起使用

Using checkedValue binding with radio buttons

本文关键字:一起 单选按钮 checkedValue 绑定      更新时间:2023-09-26

我正在尝试使用淘汰版 3 中引入的 checkedValue 绑定,带有单选按钮,但没有得到我期望的行为。

下面是一个示例:(视图模型有两个属性; list是一个数组; checkedVal是可观察的)

<div data-bind="foreach:list">
    <input type="radio" data-bind="
        checkedValue: {
            data: $data,
            index: $index(),
        },
        checked: $parent.checkedVal
    "/>
    <span data-bind="text: $data"></span>
</div>

JSFiddle

我希望单选按钮行为正常,并检查Val是包含数据和索引的对象。 checkedVal 正如我所期望的那样,但单选按钮没有选择。 奇怪的是,在我的实际代码中,行为不一致;有时无线电屁股有效,有时它们不起作用,但据我所知,它在小提琴中始终不起作用。

这是一个错误,还是我误解了它应该如何工作?

您的checkedValue绑定将变为如下函数:

function () {
    return {
        data: $data,
        index: $index(),
    };
}

每次checked绑定更新时,它都会调用此函数来获取值。但该函数始终返回一个新对象。即使对象包含相同的数据,Knockout 也不会将它们视为相同。

您可以通过将值设置为字符串来解决此问题。

    <input type="radio" data-bind="
        checkedValue: JSON.stringify({
            data: $data,
            index: $index(),
        }),
        checked: $parent.checkedVal
    "/>

或者通过绑定到一致的值。

    <input type="radio" data-bind="
        checkedValue: $data,
        checked: $parent.checkedVal
    "/>

编辑:

您可以使用遵循与 checked 相同的模式的自定义绑定,但允许比较函数。

ko.bindingHandlers.radioChecked = {
    init: function (element, valueAccessor, allBindings) {
        ko.utils.registerEventHandler(element, "click", function() {
            if (element.checked) {
                var observable = valueAccessor(), 
                    checkedValue =  allBindings.get('checkedValue');
                observable(checkedValue);
            }
        });
    },
    update: function (element, valueAccessor, allBindings) {
        var modelValue = valueAccessor()(), 
            checkedValue =  allBindings.get('checkedValue'), 
            comparer = allBindings.get('checkedComparer');
        element.checked = comparer(modelValue, checkedValue);
    }
};

然后可以按内容比较对象。

this.itemCompare = function(a, b) {
    return JSON.stringify(a) == JSON.stringify(b);
}

js小提琴:http://jsfiddle.net/mbest/Q4LSQ/

此问题似乎已在较新版本的 KO 中得到解决。 从 3.2 版开始,我不再看到我最初的问题中提到的这种行为。

这是一个工作JSFiddle,与原始版本相同,只是KO更新到3.2。