使用Knockout.js创建数据绑定复选框时未选择任何内容

Nothing selected when creating data-bound check boxes with Knockout.js

本文关键字:选择 任何内 复选框 Knockout js 创建 数据绑定 使用      更新时间:2023-09-26

我正试图用Knockout.js创建一个复选框列表。该列表本身来自数据绑定源,以及列表中的哪些项被选中。我的模型看起来像这样:

var ViewModel = function ()
{
   this.areas = [{AreaId: 1, Name: 'Test 1'}, {AreaId: 2, Name: 'Test 2'}, {AreaId: 3, Name: 'Test 3'}];
   this.AreasImpacted = ko.observableArray([1, 2]);
};

现在,我想创建一个复选框列表,标签为Test1Test 2Test 3。我想检查测试1检测2。我的HTML看起来是这样的:

<span class="areas" data-bind="foreach: areas">
  <label><input type="checkbox" data-bind="value: AreaId, checked: $parent.AreasImpacted" /><span data-bind="text: Name"></span></label>
</span>

这个确实用正确的名称绘制了每个复选框,我可以验证每个复选框的value属性设置是否正确,但没有任何内容被选中!我还尝试将this.AreasImpacted设置为仅2。当我这样做时,所有3个复选框都被选中!

完全困惑!

更新:

如果我将型号更改为:

this.AreasImpacted = ko.observableArray(['1', '2']);

然后一切如预期。

如果非要我猜测的话,我会说for-each绑定正在将每个值转换为一个字符串。我很好奇这是故意的,还是Knockout.js的bug。我希望输入的值是数字,因为这就是我将其绑定到的

提交的Bug:

由于上面的代码没有像文档中那样工作,我在GitHub上提交了一个bug。

您需要稍微更改一下,以检查您正在渲染的区域的AreaId是否包含在AreasImpacted数组中:

data-bind="value: AreaId, checked: $parent.AreasImpacted.indexOf(AreaId) >= 0"

看看这个小提琴的工作演示。

注意:使用此技术,选中或取消选中其中一个绑定复选框将不会更新数据源。

或者,您可以使数组成为字符串列表,例如:

this.AreasImpacted = ko.observableArray(['1', '2']);

请看这把小提琴的演示。


正如评论中所指出的,KnockoutJS文档似乎表明OP的原始语法应该可以工作。您甚至可以通过将数组中的项制作成字符串(demo)来实现这一点。

KnockoutJS源代码可以告诉我们为什么会发生这种情况。查看checked.js默认绑定,查看将决定是否检查输入的相关代码位:

element.checked = ko.utils.arrayIndexOf(value, element.value) >= 0;

在此背景下:

  • value是区域id的数组(数字,在OP的原始代码中)
  • element<input .../>复选框HtmlElement

因此,element.value将始终是字符串类型,这就是为什么只有当数组中的项目也是字符串时才会选中复选框的原因。

这是KnockoutJS中的错误,还是一些意外但合乎逻辑的行为:我不确定。