淘汰赛检查绑定问题

发布于 2025-01-06 21:13:05 字数 791 浏览 0 评论 0 原文

我遇到了复选框绑定无法与 KnockoutJS 2.0 配合使用的问题。我有一系列对象。这些对象的属性之一是不同对象的数组。子对象中有一些属性,其中之一是布尔值。我为每个父对象构建一个列表,并在每个父对象下显示子对象。对于每个孩子列表,我有两个视图,一个只读视图和一个编辑视图。在只读中,我有图像表示是否根据布尔属性检查该项目。这是有效的,如果我通过控制台更新布尔值,我会看到我所期望的——图像消失或根据我分配的值显示。在编辑视图中,图像被替换为复选框。当我通过控制台更新值时,我看到了相同的行为——当我期望它是时它会被检查,而当我不期望时它不会被检查。当我选中或取消选中该复选框时,问题就出现了。这样做不会更改复选框绑定到的基础值。

这是我的数据的基本想法。

[
    {
        "xxx": "yyy",
        "xxx": "yyy",
        ...
        "Displays": [
            {
            "xxx": "yyy",
            ...
                "Excluded": false,
            },
            {
            "xxx": "yyy",
             ...
                "Excluded": true,
            }
        ],
    }
]

这是绑定

<input type="checkbox" data-bind="checked: !Excluded()" />

I'm having a problem with checkbox bindings not quite working with KnockoutJS 2.0. I have an array of objects. One of the properties of those objects is an array of different objects. In the child objects there are a few properties, one of which is a boolean. I build a list for each parent object and under each parent I show the children. For each list of children I have two views, a read only and an edit view. In the read only I have images that represent whether or not the item is checked based on the boolean property. This works and if I update the boolean value through the console, I'm seeing what I would expect--the image goes away or displays based on the value I assign. In the edit view, the images are replaced with a checkbox. I see the same behavior when I update the value through the console--it is checked when I expect it to be and not when I don't. The problem comes in when I check or uncheck the checkbox. Doing this doesn't change the underlying value the checkbox is bound to.

Here's the basic idea of my data.

[
    {
        "xxx": "yyy",
        "xxx": "yyy",
        ...
        "Displays": [
            {
            "xxx": "yyy",
            ...
                "Excluded": false,
            },
            {
            "xxx": "yyy",
             ...
                "Excluded": true,
            }
        ],
    }
]

Here's the binding

<input type="checkbox" data-bind="checked: !Excluded()" />

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一人独醉 2025-01-13 21:13:05

问题是,这里的“选中”是双向绑定:需要读取绑定属性以生成正确的视图,但在单击复选框时也需要更新。将此与以下绑定进行对比:

<span data-bind="text: 'your name is ' + name()"></span>

当仅读取表达式时,因此您可以使用表达式(并且需要解开可观察值)。

因此,您需要直接绑定到可观察属性,而不是“解包”它添加“()”,它将在需要时通过敲除来完成,无论是读取还是写入:

<input type="checkbox" data-bind="checked: Excluded" />

请参阅 http://jsfiddle.net/saurus/usKwA/ 一个简单的例子。请注意复选框标签如何在更改时更新,显示模型已更新并且渲染正确触发。

如果您需要否定该值(以便在值为 false 时选中该复选框),您可以添加一个可写的计算可观察量,如 http://knockoutjs.com/documentation/compulatedObservables.html 部分“可写计算的可观察量”,或者您可以否定中的数据视图模型,在发送数据之前在服务器上执行,或者在填充视图模型之前在客户端上执行。

希望这有帮助。

the problem is that "checked" here is a bidirectional binding: the bound property needs to be read to generate the correct view, but needs also to be updated when you click on the checkbox. Contrast this to a binding like:

<span data-bind="text: 'your name is ' + name()"></span>

when the expression is only read, so you can use an expression (and you need to unwrap the observable).

So, you need to bind directly to the observable property, without "unwrapping" it adding '()', it will be done by knockout when needed, both for read and write:

<input type="checkbox" data-bind="checked: Excluded" />

See http://jsfiddle.net/saurus/usKwA/ for a simple example. Note how the checkbox labels are updated on change, showing that the model is updated and the rendering triggers correctly.

If you need to negate the value (so that the checkbox is checked when the value is false), you can add a writeable computed observable, as explained on http://knockoutjs.com/documentation/computedObservables.html section "Writeable computed observables", or you can negate the data in the viewmodel, doing it on the server just before sending the data, or on the client before populating the viewmodel.

hope this helps.

来日方长 2025-01-13 21:13:05

我知道我的答案有点晚了,但我今天遇到了这个问题,这是我能找到的与该问题相关的最接近的线程,而且似乎没有解决该问题的答案。这是我的解决方案。

本质上,问题在于淘汰赛确实希望您的 viewModel 值是字符串,而不是布尔值,但这并不总是实用。因此,我创建了一个名为“isChecked”的绑定,它严格适用于布尔值。 注意:这仅适用于可观察的属性。

ko.bindingHandlers.isChecked = {
    getElementDeclaredValue: function (element) {
        var declaredValue = element.getAttribute("value");

        // If a value is provided, we presume it represents "true",
        // unless its explicitly "false". If no value is provided, we
        // presume that a checked state would equal "true".
        return declaredValue && Boolean.isBool(declaredValue)
            ? Boolean.parse(declaredValue)
            : true;
    },

    init: function (element, valueAccessor) {
        var updateHandler = function () {
            var declaredValue = ko.bindingHandlers.isChecked.getElementDeclaredValue(element);
            var elementValue = element.checked ? declaredValue : !declaredValue;

            var modelValue = valueAccessor();
            var currentValue = ko.utils.unwrapObservable(modelValue);

            if (elementValue === currentValue)
                return;

            if (ko.isObservable(modelValue)) {
                modelValue(elementValue);
            }
        };

        ko.utils.registerEventHandler(element, "click", updateHandler);
    },

    update: function (element, valueAccessor) {
        var elementValue = ko.bindingHandlers.isChecked.getElementDeclaredValue(element);
        element.checked = elementValue === ko.utils.unwrapObservable(valueAccessor());
    }
};

两个布尔方法(“parse”和“isBool”)定义如下:

Boolean.isBool = function (value) {
    return (/^(?:true|false)$/i).test(value);
};

Boolean.parse = function (value) {
    return (/^true$/i).test(value);
};

我将忽略任何说我不应该修改内置对象原型的注释;我会尽力而为;-)。

用法与checked绑定相同。 “value”属性是可选的,除非您希望检查状态表示 false:

<input type="radio" id="rbNewClaim" name="ClaimType" value="false" data-bind="checked: isExistingClaim" />

希望这对某人有帮助。

I know my answer is a bit late to the game here, but I had this problem today and this was the closest thread I could find related to the problem, and it doesn't seem to have an answer that solves it. So here's my solution.

Essentially, the issue is that knockout really wants your viewModel values to be a string, not a boolean, but this isn't always practical. So, I created a binding called "isChecked" which works strictly with booleans. Note: This will only work with observable properties.

ko.bindingHandlers.isChecked = {
    getElementDeclaredValue: function (element) {
        var declaredValue = element.getAttribute("value");

        // If a value is provided, we presume it represents "true",
        // unless its explicitly "false". If no value is provided, we
        // presume that a checked state would equal "true".
        return declaredValue && Boolean.isBool(declaredValue)
            ? Boolean.parse(declaredValue)
            : true;
    },

    init: function (element, valueAccessor) {
        var updateHandler = function () {
            var declaredValue = ko.bindingHandlers.isChecked.getElementDeclaredValue(element);
            var elementValue = element.checked ? declaredValue : !declaredValue;

            var modelValue = valueAccessor();
            var currentValue = ko.utils.unwrapObservable(modelValue);

            if (elementValue === currentValue)
                return;

            if (ko.isObservable(modelValue)) {
                modelValue(elementValue);
            }
        };

        ko.utils.registerEventHandler(element, "click", updateHandler);
    },

    update: function (element, valueAccessor) {
        var elementValue = ko.bindingHandlers.isChecked.getElementDeclaredValue(element);
        element.checked = elementValue === ko.utils.unwrapObservable(valueAccessor());
    }
};

The two Boolean methods ("parse" and "isBool") are defined as follows:

Boolean.isBool = function (value) {
    return (/^(?:true|false)$/i).test(value);
};

Boolean.parse = function (value) {
    return (/^true$/i).test(value);
};

I'll ignore any comments that say I shouldn't be modifying a built-in object prototype; I'll do as I damn well please ;-).

Usage is the same as the checked binding. The "value" attribute is optional, unless you want the checked state to represent false:

<input type="radio" id="rbNewClaim" name="ClaimType" value="false" data-bind="checked: isExistingClaim" />

Hope this helps someone.

深白境迁sunset 2025-01-13 21:13:05

我放弃了尝试让它与布尔值一起工作,并创建了一个选定对象的数组并以这种方式处理它。这不是最佳解决方案,但我厌倦了与之抗争。

I gave up trying to get this to work with the bool values and created an array of selected objects and handled it that way. It isn't the optimal solution, but I was tired of fighting this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文