所以我对此的看法如下。
- 您有一组“选项”。每个选项都有一些属性和一个 Id
- 您有一组“项目”,其中每个项目都有一个属性,其中包含一个对象,该对象等于选项中的一个对象。所以每个“项目”都有一个选定的“选项”。
与 c# 和其他高级环境不同,javascript 没有内置的相等概念。当您执行类似操作objA == objB
时,它将检查引用相等(对于数字和字符串等原始类型不正确),即这两个变量实际上引用了同一个对象。例如,在 .NET 中,一个类可以实现IEquatable<T>
(和一个运算符重载),从而objA == objB
导致一些自定义比较,这将确定两个不同的对象是否可以被视为相等。
因此,在使用淘汰赛和下拉等时,重要的是要记住,为了让淘汰赛匹配,您必须确保比较的对象确实相同。
在您的情况下,我对您的模型进行了一些调整。我假设项目的选择选项属性称为SelectedOption。
function model(options, items) {
self = this;
self.options = options;
self.items = ko.mapping.fromJS(items);
// Loop over each of the items and swap out the server-side provided option object
// with the corresponding option from the options parameter.
ko.utils.arrayForEach(self.items(), function(item) {
item.SelectedOption = ko.observable(
ko.utils.arrayFirst(self.options, function(option) { return option.Id == item.SelectedOption.Id(); })
);
});
}
由于您使用的是 ko.mapping 我假设选项和项目参数以某种方式作为普通 javascript 对象提供(Ajax,内联 js)。
opts = [
{ Id: 1, Name: "Option 1" },
{ Id: 2, Name: "Option 2" },
{ Id: 3, Name: "Option 3" }
];
var items = [
{ Id: 1, Name: "Item 1", SelectedOption: { Id: 1, Name: "Option 1" } },
{ Id: 2, Name: "Item 2", SelectedOption: { Id: 2, Name: "Option 2" } },
{ Id: 3, Name: "Item 3", SelectedOption: { Id: 3, Name: "Option 3" } }
];
var viewModel = new model(opts, items);
由于每个项目的 SelectedOption 参数中包含的选项与选项属性中的选项完全相同,因此淘汰赛现在能够比较它们是否相等,您可以在绑定中使用它,如下所示:
<div data-bind="foreach: items">
<select data-bind="options: $parent.options, optionsText: 'Name', value: SelectedOption"></select>
</div>
在 jsfiddle 进行测试:http: //jsfiddle.net/niik/HDsKC/