【问题标题】:Knockout radio button binding with boolean带有布尔值的淘汰赛单选按钮绑定
【发布时间】:2016-12-01 01:52:25
【问题描述】:

根据我在运行时创建的Fiddle,它不会按预期将值绑定到“no Blue”选项。

var viewModel = {    
    isBlue: ko.observable(false)
    //isBlue: ko.observable("false") this works
};

正如我在那里提到的,当我传递一个字符串值“false”时,它会执行绑定。很明显,knockout 也可以进行类型比较。

在我的应用程序中,我使用的是创建视图模型的 komapper。对于 boolean 中的属性,它创建 bool 值并初始化 bool 中的变量。 我需要将它们转换为字符串吗?在输入单选按钮元素中,我们将始终使用字符串值。我可以为复选框使用布尔值吗?

我尝试使用“checkedValue”仍然没有成功。

【问题讨论】:

  • 如果您包含重现问题/理解问题所需的所有代码在问题本身中会有所帮助,这样该页面即使如果到 jsfiddle 腐烂或 jsfiddle 的链接已关闭。

标签: knockout.js knockout-mapping-plugin


【解决方案1】:

认为您遇到了一个已在更高版本的淘汰赛中修复的错误。

它应该工作的方式(和你尝试过的一样):

<input name="Test" type="radio" data-bind="checkedValue: true, 
                                           checked: isBlue" />Blue
<input name="Test" type="radio" data-bind="checkedValue: false, 
                                           checked: isBlue" />No Blue
ko.applyBindings({
  isBlue: ko.observable(false)
});

如果您包含淘汰赛版本 3.4,它会按预期工作:

ko.applyBindings({
  isBlue: ko.observable(false)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<label>
  <input name="Test" type="radio" data-bind="checkedValue: true, checked: isBlue" /> Blue
</label>
<label>
  <input name="Test" type="radio" data-bind="checkedValue: false, checked: isBlue" /> No Blue
</label>
<br />
<strong style="color: green">3.4.0: Does work</strong>

当您包含您在小提琴中使用的版本(2.1.0)时,它不会:

ko.applyBindings({
  isBlue: ko.observable(false)
});
<script src="https://cloud.github.com/downloads/knockout/knockout/knockout-2.1.0.js"></script>

<label>
  <input name="Test" type="radio" data-bind="checkedValue: true, checked: isBlue" />Blue
</label>
<label>
  <input name="Test" type="radio" data-bind="checkedValue: false, checked: isBlue" />No Blue
</label>
<br />
<strong style="color: red">2.1.0: Does not work</strong>

编辑:经过更多挖掘:我认为这不是 2.1.0 中的错误; checkedValue 那时甚至都不存在!

查看源代码,您会注意到获取检查值的逻辑在 2.1.0 和更高版本之间非常不同:

在 2.1.0 中:

if (element.type == "checkbox") {
  valueToWrite = element.checked;
} else if ((element.type == "radio") && (element.checked)) {
  valueToWrite = element.value;
}

在 3.4.0 中:

 var checkedValue = ko.pureComputed(function() {
   // Treat "value" like "checkedValue" when it is included with "checked" binding
   if (allBindings['has']('checkedValue')) {
     return ko.utils.unwrapObservable(allBindings.get('checkedValue'));
   } else if (allBindings['has']('value')) {
     return ko.utils.unwrapObservable(allBindings.get('value'));
   }

  return element.value;
});

所以一个明确的答案是:更新到 3.4.0,或者创建一个自定义的检查绑定来实现 3.4.0 的行为(如果版本更新会破坏你的项目)

【讨论】:

  • CheckedValue 绑定实际上适用于 knockout-3..04,完全没有问题。提到小提琴中的旧版本(2.1.0)是我的错。这个答案非常有用,因为您在两个版本中都包含了淘汰行为。
【解决方案2】:

是的。 src 绑定在内部只返回element.value,对于浏览器来说是一个字符串。检查the source file,使用此缩写/注释代码获取与被检查相关的值:

var checkedValue = ko.pureComputed(function() {
    // Abbreviated, first KO does some stuff for other cases, but
    // in the end it'll do:

    return element.value; // Where `element` is the actual DOM element.
});

通常,一个布尔值将由一个复选框表示,您只在一半的情况下遇到问题(在这些情况下,您需要类似“an inverse checked binding”的内容)。

解决方案包括您提到的那个(使用字符串)以及使用可写计算在实际可观察​​对象前面,例如:

viewModel.viewIsBlue = ko.computed({
  read: function() { return viewModel.isBlue().toLocaleString(); },
  write: function(newVal) { viewModel.isBlue(newVal === 'true'); }
});

如果您发现自己经常重复上述操作,您也可以使用具有类似功能的自定义扩展程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-03
    • 2016-05-10
    • 2013-03-22
    • 1970-01-01
    • 2013-12-03
    • 1970-01-01
    • 2021-12-24
    • 2014-02-26
    相关资源
    最近更新 更多