I've got a problem with dynamic binding to select control using knockout. What I want to achieve is a piece of code that binds the observableArray of observable objects to the select options. The 'objects' inside the observableArray change constantly.
The object stored in the observableArray, let's call it sampleObj, has a few properties (which are ko.observables) like name, lastName and phoneNumber. I would like to display as select options lastNames of all objects stored in the observableArray.
My binding to the observable inside the cshtml looks as follows:
<select data-bind="options: sampleObservableArray, optionsText: lastName, optionsCaption: 'choose...'"></select>
and it does not display anything besides the 'choose...' text. The content of the sampleObservableArray is updating in the js and I can console.log it whenever I want. Is there anything wrong in the way I bind the values or maybe should I somehow force refreshing of the select control? Of course as a complete amateur, I have tried I think all possible combinations of using and not using parethnesis :) but still with no effect.
sampleObservableArray - ko.observableArray that contains sampleObj's
sampleObj - ko.observable with a few properties like name, lastName and phoneNumber where all are ko.observables as well.
EDIT: Answering for @Tomalak's ask there is a code for better clarity. Firstly, sampleObj model:
define('sampleObj',
['ko'],
function (ko) {
var
SampleObj = function () {
var self = this;
self.name = ko.observable();
self.lastName = ko.observable();
self.phoneNumber = ko.observable();
return self;
};
return SampleObj;
});
then adding the sampleObj objects to the observableArray:
// newData is an argument of a function triggered by signalR action, and returns strings as its properties
var sampleObj = ko.observable(new SampleObj()
.name(newData.name)
.lastName(newData.lastName)
.phoneNumber(newData.phoneNumber);
var sampleObjEntry = ko.utils.arrayFirst(sampleObservableArray(), function (item) {
return item().phoneNumber() === newData.phoneNumber;
});
// if object with the phoneNumber already exits replace it, if not - add
if (!sampleObjEntry) {
sampleObservableArray.push(sampleObj);
} else {
sampleObservableArray()[sampleObservableArray().indexOf(sampleObjEntry)] = sampleObj;
sampleObservableArray.valueHasMutated();
}
Don't know if it helps.
optionsText:
binding is supposed to be a string) – TomalakoptionsText
binding also works with a function – GôTô'lastName'
there, notlastName()
. In this case a function result is used, which could be anything and not necessarily refer to a property on any object insampleObservableArray
. So I tend to say it's an error. – TomalakoptionsText: 'lastName'
. (Hint: You're telling knockout the name of the property it should use.) Also - why are you wrappingSampleObj
in another observable? That should be unnecessary. – Tomalak