Initial selection in dropdown menus using KnockoutJS objects

I have a model that looks something like this (not the actual code, so not against a possible nebula).

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

The options list contains a list of objects that can be selected from the drop-down list. items also contains a list of objects in which each object has the same object, such as one in the list of options.

Then I listed the list of items and displayed a drop-down list on each line. I need an object in the current elements from the list of elements to select the selected option. However, when I do not set optionValue, but try to only combine on the whole object, it does not work ... My observable then, however, works fine, and all the sign fields for the whole object are updated with a new choice. However, I got the original choice for working with optionValue and Id , as shown below.

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

Now my problem is that only the element associated with the identifier is updated? I need all the properties of the current element to be updated, even if it is only an ID that changes now when I change something in the drop-down list.

How can I do it?

+2
source share
1 answer

So, I understand that this is the following.

  • You have a set of "options." Each parameter has some properties and Id
  • You have a set of "elements", where each element has one property containing an object that is equal to one of the objects inside the options. Therefore, each β€œitem” has a selected β€œoption”.

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 the reference equality (not true for primitive types such as numbers and strings), i.e. That two variables actually refer to the same object. For example, in .NET a class can implement IEquatable<T> (and operator overloading), so objA == objB leads to some user comparison that will determine if two different objects can be considered equal.

Therefore, when you work with a knockout and drop out, and therefore it is important to remember that to match the knockout you need to make sure that the objects being compared are really the same.

In your case, I changed your model a bit. I suggested that the property of the item selection option 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(); }) ); }); } 

Since you are using ko.mapping, I assume that the parameters and parameters of the elements are provided as simple javascript objects in some way (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); 

Since the parameters contained in the SelectedOption parameter for each element are exactly the same as those in the properties of the options properties can now compare them for equality, and you can use them in your bindings as such:

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

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

+6
source

Source: https://habr.com/ru/post/1481342/


All Articles