11
votes

I want to combine two return values in my optionsText field, I thought this would be simple, but I am apparently wrong. I'm also using a value for the options field that is outside the normal view model. Here is the original:

<select style="width: 180px" data-bind="visible: false, value: fields.person, options: $root.extra.personList, optionsText: 'FirstName', optionsValue: 'LastName' }, select2: {}">

This works fine, displays the person's FirstName and sets the value as LastName.

This next piece throws an error:

<select style="width: 180px" data-bind="visible: false, value: fields.person, options: $root.extra.personList, optionsText: function (item) { return item.FirstName() + '-' + item.LastName() }, optionsValue: 'LastName', select2: {}">

Uncaught TypeError: Property 'FirstName' of object # is not a function

2
You sure FirstName and LastName are observables? If you're not sure, try this: ko.unwrap(item.FirstName) + '-' + ko.unwrap(item.LastName)sroes
I am not sure, I will try that out.Organiccat
Before you start adding that into your view, consider moving that function into your view model and invoking it. It will lead to much cleaner code.Jeff Mercado
@JeffMercado This, and make it a ko.computed.ach
Thanks sroes, I didn't manage the previous model so I didn't know they weren't observable. Could you make that an answer and I'll mark it?Organiccat

2 Answers

19
votes

You sure FirstName and LastName are observables? If you're not sure, try this:

optionsText: function(item) { return ko.unwrap(item.FirstName) + '-' + ko.unwrap(item.LastName); }

Or better yet, create a computed in your viewmodel:

self.FullName = function() {
    return ko.unwrap(self.FirstName) + '-' + ko.unwrap(self.LastName);
};

And:

optionsText: 'FullName'
0
votes

how optionsText works is it looks for the property 'FirstName' on the options array that is is bound to. So if your extra person array has a 'FirstName' and a 'LastName' you can extend a computed property to hold full name.

function ViewModel(){
    var self = this; 
    self.peopleList = ko.observableArray(); 
}
function Person(f, l){
    var self = this; 
    self.FirstName = ko.obserable(f); 
    self.LastName = ko.obserable(l); 
    self.FullName = ko.computed(function(){
        return self.FirstName() + ' ' + self.LastName();
    });
}

If they are not observables you don't want to be calling them [ what () does ] it would in that case I would just have a function living on the view model that puts them together which you call from the binding.