我的网站上的网页出现了一个奇怪的问题。我正在使用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]);
}
现在,当页面加载时,正确选中了复选框。
答案 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/