当数组由对象组成时,Knockout checkedValue绑定不起作用

时间:2014-02-17 06:50:22

标签: javascript jquery asp.net-mvc knockout.js

我的网站上的网页出现了一个奇怪的问题。我正在使用ASP.NET MVC将模型数据发送到页面。

我正在显示基于Javascript数组中对象的复选框列表。页面加载时,它会正确显示项目,但不会选择所选项目数组中的项目。

以下是HTML的样子。

<!-- ko foreach: items -->
    <p>
        <input type="checkbox"
               data-bind="checkedValue: $data, checked: $root.selectedItems" />
        <span data-bind="text: Name"></span>
    </p>
<!-- /ko -->

以下是Javascript的样子。

var Item = function (id, name) {
    this.Id = id;
    this.Name = name;
};

var model = {
    items = ko.observableArray([]),
    selectedItems = ko.observableArray([])
};

@foreach (var serverItem in serverItems) {
    @:model.items.push(new Item('@serverItem.Id', '@serverItem.Name'));
}
@foreach (var selectedServerItem in selectedServerItems) {
    @:model.selectedItems.push(new Item('@selectedServerItem.Id', '@selectedServerItem.Name'));
}

ko.applyBindings(model);

你会认为它会被选中,因为对象是相同的,但它没有。当我选择复选框时,它会向selectedItems数组添加其他项目,而不是使用现有数据。

['1', 'Business To Business'], ['2', 'Business To Consumer'], ['1', 'Business To Business']

任何人都可以向我解释为什么会这样吗?为什么Knockout不理解需要根据对象而不是基元来检查复选框?

解决方案我最终得到了:

var items = [];
@foreach (var serverItem in serverItems) {
    @:items[@serverItem.Id] = {Id: '@serverItem.Id', Name: '@serverItem.Name'};
    @:model.items.push(items[@serverItem.Id]);
    if (selectedServerItems.Any(si => si.Id == serverItems.Id)
        @:model.selectedItems.push(items[@serverItem.Id]);
}

现在,当页面加载时,正确选中了复选框。

1 个答案:

答案 0 :(得分:3)

对象是相同的,但它们是不同的实例。 Knockout执行==(或者===)来比较项目,并且在JavaScript中对于对象的2个不同实例将始终返回false,即使在内部它们是相同的。但是,这适用于字符串。

var foo1 = {foo: 1};
var foo2 = {foo: 1};
var foo3 = foo1;

console.log(foo1 == foo2); // false
console.log(foo1 == foo3); // true

你可以看到这个小提琴的行动...... http://jsfiddle.net/Nk86C/1/