使用KnockoutJS对带有对象的下拉列表进行初始选择

Rir*_*iri 2 javascript knockout-mapping-plugin knockout.js

我有一个看起来像这样的模型(不是实际的代码所以不介意可能的错误输入).

model = function(option, items) {
    self = this;
    self.options = options;
    self.items = ko.mapping.fromJS(items);
}
Run Code Online (Sandbox Code Playgroud)

options的coantains列表对象,人们可以从一个下拉列表中选择.在items还包含对象的列表,其中每个对象具有一个像中的选项列表一个相同的对象.

然后,我遍历项目列表并在每行上显示一个下拉框.我这里需要将项目列表中当前项目中的对象作为选定选项.然而,当我没有设置optionValue但只尝试匹配整个对象时它不起作用...然后我的observable工作正常,并且整个对象的所有订阅字段都使用新选择进行更新.然而,我得到了初始选择以使用optionValue,Id如下所示.

<select data-bind="options: $parent.options, optionsValue:'Id', optionsText: 'Name', value: item.Id"></select> 
Run Code Online (Sandbox Code Playgroud)

我现在的问题是只有绑定到Id的元素才会更新?我需要更新当前项目的所有属性,即使它只是当我在下拉列表中更改内容时现在更改的ID.

我该怎么做?

Mar*_*son 6

所以我对此的看法如下.

  • 你有一套'选项'.每个选项都有一些属性和Id
  • 您有一组"项目",其中每个项目都有一个属性,其中包含一个对象,该对象等于选项中的一个对象.因此,每个"项目"都有一个选定的"选项".

与c#和其他高级环境不同,javascript没有内置的平等概念.当你做类似的事情时objA == objB,它将检查引用相等性(对于数字和字符串等基本类型不是这样),即两个变量实际引用相同的对象.例如,在.NET中,类可以实现IEquatable<T>(和运算符重载),从而objA == objB导致一些自定义比较,这将确定两个不同的对象是否可以被认为是相等的.

因此,当使用淘汰赛和下拉赛道时,重要的是要记住,为了使淘汰赛匹配,你必须确保比较对象确实是相同的.

在你的情况下,我已经调整了你的模型.我假设items的selection选项属性叫做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(); })
        );
    });
}
Run Code Online (Sandbox Code Playgroud)

由于您正在使用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);
Run Code Online (Sandbox Code Playgroud)

由于每个项目的SelectedOption参数中包含的选项与options属性中的选项完全相同,因此敲除现在可以比较它们的相等性,您可以在绑定中使用它:

<div data-bind="foreach: items">
    <select data-bind="options: $parent.options, optionsText: 'Name', value: SelectedOption"></select>
</div>
Run Code Online (Sandbox Code Playgroud)

在jsfiddle测试:http://jsfiddle.net/niik/HDsKC/