Knockout JS Checkbox绑定

时间:2014-02-05 22:44:55

标签: jquery knockout.js

当jquery在页面中时,我遇到了一个复选框绑定和一个计算的observable的问题。

self.Guaranteed = ko.computed(function() {
    var result;
    result = self.IsGuaranteed() && (self.IsAllowed() || self.IsAllowed2());
    console.log("evaluated");
    if (result) {
        self.IsGuaranteed(false);
    }
    return result;
}, self);

jsfiddle of runnable code

因此,当我在页面中不包含jquery时,我得到了预期的行为,但是当jquery在页面上时,依赖关系未在计算的observable中正确注册,并且在满足条件时,保证的复选框永远不会取消选中。条件文本可能会也可能不会显示,具体取决于计算的重新计算。不幸的是,我不能只是从页面中删除jquery,还有其他想法吗?

编辑:

这与上面的预期行为相同,但没有加载jQuery:working jfiddle

此外,这里是淘汰线中重置复选框的行:

// For click events on checkboxes, jQuery interferes with the event handling in an awkward way:
// it toggles the element checked state *after* the click event handlers run, whereas native
// click events toggle the checked state *before* the event handler.
// Fix this by intecepting the handler and applying the correct checkedness before it runs.
var originalHandler = handler;
handler = function(event, eventData) {
    var jQuerySuppliedCheckedState = this.checked;
    if (eventData)
        this.checked = eventData.checkedStateBeforeEvent !== true;
    originalHandler.call(this, event);
    this.checked = jQuerySuppliedCheckedState; // Restore the state jQuery applied
};

2 个答案:

答案 0 :(得分:1)

我不太确定为什么你会得到“正确”的行为,考虑到这个模式,在计算中,需要特别考虑。问题是您正在修改计算中的计算依赖项self.IsGuaranteed。见Note: Why circular dependencies aren’t meaningful。如果您必须使用此设置,请考虑使用peek链接中的建议。

这可能是更复杂的设置的简化示例,但如果所需的功能是阻止选择guaranteed,为什么不禁用该元素呢?

模型

self.isGuaranteeable = ko.computed(function(){         
    return  !(self.IsAllowed() || self.IsAllowed2());  
});

HTML

<input data-bind="checked: IsGuaranteed, enable: isGuaranteeable"   id="IsGuaranteed" name="IsGuaranteed" type="checkbox" value="true"> <span>Guaranteed</span> 

说明

查看添加了一些调试功能的example

案例1 :您选择Allowed,然后选择Guaranteed。然后单击以打印isGuaranteed可观察值。

[09:45:00.623] Computing (computed)
[09:45:00.623] IsGuaranteed: (assigning) false
[09:45:00.623] IsGuaranteed: (assigning) true
[09:45:38.430] Actual value: false

当您输入计算值时,IsGuaranteed的值被设置为true。您遇到了要阻止的状态,并将observable设置为false。但问题是,“Knockout在评估时不会重新开始计算评估”。在计算的“第一次”传递上呈现的跨度和计算的依赖性的重新分配不会触发重新评估。因此,文本保留在屏幕上。您中断了原始值设置true,该设置最后解析而选中了复选框,但幕后的实际值为false

案例2 :选择Guaranteed,然后选择Allowed,然后打印实际值。

[09:58:01.367] Computing (computed)
[09:58:01.367] IsGuaranteed: (assigning) true
[09:58:02.199] Computing (computed)
[09:58:02.199] IsGuaranteed: (assigning) false
[09:58:03.054] Actual value: false

第一个选择会恰当地触发所有内容。选择Allowed强制计算得到的评估和“坏”状态会触发IsGuaranteed的重新分配。由于该值不是计算机的原始触发器,因此它正确地分配了值,但是,后端现在处于应该隐藏警告文本的状态,但是由于循环依赖性而没有。

答案 1 :(得分:1)

仍然不完全清楚你实际上希望如何使用它,但这是我对你想要的想法的看法。

http://jsfiddle.net/9Z7vR/7/

我创建了一个单独的computed来控制enable复选框的Guaranteed状态:

self.isEnabled = ko.computed(function() {
    return !self.IsAllowed() && !self.IsAllowed2();
});

然后我删除IsGuaranteedGuaranteed的依赖关系:

self.Guaranteed = ko.computed(function() {
    var result;
    result = (self.IsAllowed() || self.IsAllowed2());
    console.log("evaluated");
    if (result) {
        self.IsGuaranteed(false);
    }
    return result;
}, self);

现在,如果您点击AllowedAllowed2,则Guaranteed将被停用。如果选中Guaranteed,然后您选中其他复选框,则Guaranteed将取消选中(并已停用)。

不确定这是否是你想要实现的(如果不是,你需要解释完全你想要的东西) - 但请注意,我不会使用计算属性取消选中{ {1}}复选框。我会订阅IsGuaranteedIsAllowed属性,并在那里更改IsAllowed2属性。