使用KnockoutJS对带有对象的下拉列表进行初始选择 [英] Initial selection on dropdowns with objects using KnockoutJS

查看:76
本文介绍了使用KnockoutJS对带有对象的下拉列表进行初始选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a model that looks something like this (not actual code so don't mind the possible mistyping).

model = function(option, items) {
    self = this;
    self.options = options;
    self.items = ko.mapping.fromJS(items);
}

期权 coantains可以在下拉列表中选择的 对象 列表。 项目还包含一个对象列表,其中每个对象都有一个相同的对象,如options-list中的对象。

The options coantains list of objects that one can select from in a dropdown. The items also contains a list of object where each object has a identical object like one in the options-list.

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

I then foreach over the items list and display an dropdown box on each row. I here need the object in the current items from the items list to be the selected option. When I however don't set an optionValue but only try to match on whole object it doesn't work ... My observable then however works fine and all the subscribing fields for the whole object get updated with the new selection. I however got the initial selection to work with optionValue and Id like below.

<select data-bind="options: $parent.options, optionsValue:'Id', optionsText: 'Name', value: item.Id"></select> 

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

My problem now is that only the element bound to the Id gets updated? I need to have all the properties of the current item updated even if it's only the Id that changes now when I change something in the dropdown.

我该怎么做?

推荐答案

所以我对此的看法如下。

So my take on this is the following.


  • 你有一套'选项'。每个选项都有一些属性和Id

  • 你有一组'items',其中每个项目都有一个属性,其中包含一个等于其中一个对象的对象选项。所以每个'item'都有一个选中的'选项'。

  • You have a set of 'options'. Each option has some properties and an Id
  • You have a set of 'items' where each item has one property containing an object which equals one of the objects inside options. So each 'item' has a selected 'option'.

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

Unlike c# and other high-level environments javascript does not have a built-in concept of equality. When you do something like objA == objB it will check for reference equality (not true for primitive types such as numbers and strings), ie that the two variables actually reference the same object. In .NET for example a class could implement IEquatable<T> (and a operator overload) so that objA == objB results in some custom comparison which will determine whether or not the two different objects could be considered equal.

因此,当使用淘汰赛和下拉时,这一点很重要为了让淘汰赛匹配,你必须确保比较对象确实是相同的。

So when working with knockout and drop down and such it's important to remember that in order for knockout to match you'll have to ensure that the compared objects are indeed the same.

在你的情况下,我已经调整了你的模型了一下。我假设项目的选择属性称为 SelectedOption

In your case I've tweaked your model a bit. I've assumed that the selection option property of items is called 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我假设选项和items参数以某种方式提供为普通的javascript对象(Ajax,内联js)。

Since you're using ko.mapping I'm assuming that the options and items parameters are provided as plain javascript objects somehow (Ajax, inline 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参数中包含的选项与选项中的选项完全相同属性knockout现在能够比较它们的相等性,你可以在你的绑定中使用它:

Since the options contained in the SelectedOption parameter of each item is the exact same as the ones in the options property knockout is now able to compare them for equality and you can use it in your bindings as such:

<div data-bind="foreach: items">
    <select data-bind="options: $parent.options, optionsText: 'Name', value: SelectedOption"></select>
</div>

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

Test it out at jsfiddle: http://jsfiddle.net/niik/HDsKC/

这篇关于使用KnockoutJS对带有对象的下拉列表进行初始选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆