Knockout JS mappings
Marco Franssen /
6 min read • 1114 words
Knockout JS is a JavaScript library for creating MVVM JavaScript libraries. In a previous post I already showed some of the cool features of Knockout.
http://marcofranssen.nl/knockout-that-cascading-dropdown/
If you want to spike your knowledge on Knockout a little more first, please visit Knockout's documentation.
In this article I want to zoom in on the Knockout mapping plugin. The Knockout mapping plugin enables you to easy map your JSON object into an observable JavaScript object. So here is a short example of what you'll be able to do with it. So when you do an ajax request and receive a JSON result you can for example do the following.
So what we are doing is making a request to some url which returns us a person JSON object. Then we parse the JSON to a regular JavaScript object, followed by mapping it into our view model. Last thing we do is binding the view model to the DOM nodes in our person DOM node (could be a div element or whatever). This creates the same view model object as we would do it by hand, like this.
So the mapping plugin easily maps our JSON into an observable view model. But what if we want to skip some properties of our JSON or just don't want to wrap them into an observable. Well you definitely don't have to fall back on writing the object completely by hand. We can simply configure our mapping in an object and pass that into our call to ko.mapping.fromJS.
By passing in the following mapping to the mapping plugin we tell the mapping plugin to ignore the twitter and webpage properties. We only want to copy the value of the personId and age property (Not wrap it in a ko.observable) and we configured our lastName property to be transformed to upper-case before putting it in an observable. When we would have done this by hand our code could have looked like this.
Now you're maybe thinking why would I skip the observable wrapping for some properties…. The best reason to do this is when you know the property won't change (by user or update from server). Observables are quite expensive when you have a lot of them and require more memory. So when you have for example a big collection of persons in a table you could skip the observables for some properties to save memory and gain a small performance boost.
The mapping plugin can also be used when you get a collection of persons from the server. What you basically do is creating a view model and add the persons to the observable collection of your view model.
With above example the person object is just a plain JavaScript object without observables. We can change that by creating another view model for each person. Probably you also want to check if the person isn't already in the observable array and so on. So imagine what amount of code you probably are going to put into the for loop. Luckily we have the mapping plugin.
First of all I will define a constructor / view model for my person objects. We just use the mapping defined before and adding a computed property to our view model by hand. You can of course add as many properties as you want by hand, to extend your person object with more functionality.
I also create a constructor for my root view model. This way I can also encapsulate the mapping logic and for example create multiple instances of it. Lets imagine we want to have a company view model containing employees. So we get some JSON from the server containing an array of persons called employees and some other properties. The company's name we will convert to uppercase and we will ignore the companies address and website properties.
Note we create a new person view model for each of the persons in our employees array. The PersonViewModel is responsible for its own mapping (defined in our constructor). We also defined a key for our person object so Knockout knows what makes a person unique. Also note that we didn't customized the way personId is mapped within our person view model.
So everything not specified in the mapping object will by default be wrapped in an observable.
So when we do a request we can instantiate our view model like this.
We make a call to some url returning the information of a company in JSON format. Create a new CompanyViewModel and apply the bindings. All the mapping logic is in the constructors. See this jsFiddle for a complete example.
Thanks again for reading my article. Please write a comment and share it with your friends and colleagues.