2

我正在尝试使用 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]);
};

现在,我想创建一个带有标签Test 1Test 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.AreasImpacted2. 当我这样做时,所有 3 个复选框都被选中!

完全糊涂了!

更新:

如果我将模型更改为:

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

然后事情按预期工作。

如果我不得不猜测,我会说for-each绑定正在将每个值转换为字符串。我很好奇这是设计使然,还是 Knockout.js 错误。我希望输入的值是数字,因为这就是我将它绑定到的值。

提交的错误:

由于上面的代码不像记录的那样工作,我在 GitHub 上提交了一个错误。

4

1 回答 1

2

您需要进行一些更改,以检查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 中的错误,还是只是一些意外但合乎逻辑的行为:我不确定。

于 2013-02-11T23:56:54.687 回答