2011-09-26 51 views
5

我使用Ko的一个特殊的扩展版本,它在依赖的observable上使用commit()/ peek()类型的函数,这样我只在将数据提交到数据库时才将数据保存到表单上恢复取消。为什么knockoutJS中的复选框只有在选中时才写入?

问题我遇到的情况是,当我检查一个复选框时,在被保护的observable上正确调用write函数。但是,如果我取消选中复选框,则不会调用写入函数,因此当模型发送到我的MVC控制器时,复选框布尔值仍然为TRUE。

为什么knockout不能写出FALSE值?

代码为修订问题:

请参见本文的jsfiddle这里证明:http://jsfiddle.net/b2Qu2/3/

小问题

注意有其他1个问题演示 - 为某些原因,当我选中/取消选中复选框时,即使将用户界面链接到dependentObservable,窥视的值也不会在用户界面上更新。您仍然可以通过单击“peek”按钮来查看该值。

主要问题

要重现的问题:

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!! 

示例方案

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

+0

你能分享更多的代码,至于它是如何绑定/使用? –

+0

@RP尼迈耶 - 我用一些代码更新了我的问题。挣扎着这个! – jaffa

回答

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/

+0

嗨,感谢您的代码示例。我的整个代码基于基于我的第一个小提琴的protectedObservable,所以不知道我想改变它的行为/绑定。模型上的绑定使用实际的protectedObservables而不是.temps。你的例子基于reset()(如果对话框被取消/服务器错误并且commit()成功。我的模型基于反向,如果用户取消或服务器错误,则不会执行任何操作,因为已使用窥视值将数据发送到服务器。如果服务器成功,则commit()。嗯,不知道如何绕过这... – jaffa

+1

我不知道我很遵循它是如何不同。只需将所有内容绑定到'yourfield.temp'而不是'yourfield'。应该解决相同的问题。也许你可以帮助我更好地理解它在你的情况下不起作用吗?会很乐意帮助提出一个合适的替代方案。 –

+1

有没有办法确保复选框depedentObservable值总是写入,而不管它是否已经从其原始值改变。看来,这是问题,并与您的原始答案有关。我将调试语句放在我的原始代码的写入函数中,当复选框的值与原始值相反时,它只会被调用,因为不会更新被偷看的值。如果这可以解决,我将不需要用.temps替换所有的视图。希望这是有道理的!让我知道你认为是最好的前进方向。 – jaffa

相关问题