A View Inside My Head

Jason's Random Thoughts of Interest
posts - 86, comments - 178, trackbacks - 22

Override toString in Knockout ViewModel

It seems that I'm always struggling to simplify my code. As such, I was playing with Knockout today, and found that in multiple places, I needed a string containing concatenated values of multiple observables

Take this simple example of binding a dropdown to a view model, and also showing the selected value in a span. The items being bound are not simple strings, but rather, are complex objects containing multiple attributes. The string that I ultimately want to display is a concatenation of the first and last names of the employee, but without doing anything special, the rendered text will be: [object Object]

Note: I seem to be having formatting issues with embedded jsFiddle iframes... I'll just provide links to the actual fiddles.

Fiddle 1

To do the concatenation for the dropdown's items, I could have provided a function for optionsText in the options binding.

Fiddle 2

The selected object itself is being persisted in the view model as the observable named "selectedEmployee". This is what's bound to the span's text, so once you select an employee, the same [object Object] issue arises.

You can provide a simple expression to Knockout's Text binding, but you cannot "dot into" an object in order to access sub properties. However, you can use the With binding to set the context for a block of markup that is being bound, and then be able to use the simple expression in the Text binding (referencing the "properties" of that context):

Fiddle 3

This does what I wanted, but now I have that code repeated twice. I would really like to have something that performed the operation only once.

Then it dawned on me: since Knockout's default behavior for complex types is to call toString(), I should just overload the toString() function on the employee object itself. Then, I wouldn't need to do anything special!

function employee(firstName, lastName, employeeID)
{
this.employeeID = ko.observable(employeeID);
this.firstName = ko.observable(firstName);
this.lastName = ko.observable(lastName);

this.toString = ko.computed(function() { return firstName + ' ' + lastName });
}

Fiddle 4


.

Print | posted on Wednesday, January 18, 2012 12:42 PM | Filed Under [ Articles ]

Comments have been closed on this topic.

Powered by: