为什么knockoutJs中的复选框只在被选中时被写入?

时间:2011-09-26 14:29:28

标签: knockout.js

我使用Ko的特殊扩展版本,它在依赖的observable上使用commit()/ peek()类型函数,这样我只将数据保存到表单上(如果它已提交到数据库)好的)并在取消时恢复。

我遇到的问题是当我选中一个复选框时,会在受保护的observable上正确调用write函数。但是,如果取消选中该复选框,则不会调用write函数,因此当模型发送到我的MVC控制器时,复选框boolean仍为TRUE。

为什么淘汰赛没有写出FALSE值?

更新的问题代码:

请在此处查看此JsFiddle以演示:http://jsfiddle.net/b2Qu2/3/

次要问题

请注意,演示还有另外一个问题 - 出于某种原因,当我选中/取消选中该复选框时,即使将其链接到dependentObservable,也不会在UI上更新该值。您仍然可以通过点击“查看”来查看价值。按钮。

主要问题

重现问题:

1) Click 'peek' button: Shows FALSE - CORRECT

2) Check IsAdmin checkbox

3) Click 'peek' again: Shows TRUE - CORRECT

4) Uncheck IsAdmin

5) Click 'peek' again: SHOWS TRUE - INCORRECT!!

示例方案

想象一下,会显示一个对话框,其中包含Admin用户的复选框。只有1个管理员用户可以设置,如果管理员用户已经存在,则服务器响应有效/无效。 然后用户取消选中该复选框,但现在viewmodel认为该复选框始终为真?使用protectedObservable的原因是,如果服务器响应成功,则调用commit()方法,以便在UI上保留所有内容。如果用户取消对话框或发生错误,则不会覆盖原始值。

1 个答案:

答案 0 :(得分:3)

写入仅针对一个值触发的原因是因为它只会在它认为需要将不同的值写入绑定的值时触发。因此,protectedObservable的实际值不会改变。如果确实如此并且您尝试将其设置为true,则写入不会触发,因为它认为它具有正确的值。

我可能会改变它并使用类似的东西:

ko.protectedObservable = function (initialValue) {
    //private variables
    var _actual = ko.observable(initialValue),
        _temp = ko.observable(initialValue);

    //access to temp value
    _actual.temp = _temp;

    //commit the temporary value to our observable, if it is different
    _actual.commit = function () {        
        if (_temp() !== _actual()) {
            _actual(_temp());
        }
    };

    //notify subscribers to update their value with the original
    _actual.reset = function () {
        _actual.valueHasMutated();
        _temp(_actual());
    };

    return _actual;
};

使用此版本,您可以绑定field1field1.temp。你甚至不需要窥视,因为临时值和实际值都是可观察的。

看起来像这样:http://jsfiddle.net/rniemeyer/BwDYE/