Over the past couple months I have grown addicted to using Knockout.js to quickly create highly interactive views using ASP.NET MVC and WebAPI. With this combination of tooling and a single page application approach I have found this pattern to be most efficient for me:
- MVC – Serves up the views containing markup, Knockout bindings, etc.
- WebAPI – Serves up JSON to populate the views and perform CRUD operations
- Knockout.js – Takes the JSON from WebAPI and data-binds into the MVC views.
I have found that many views end up being quite similar the the C# models that WebAPI are serving up. Knockout just extends these views to make them richer and more interactive.
Coming from some pretty heavy MVC only development something quickly started to bother me:
@Html.TextBoxFor(m => m.FirstName) //MVC
seems a whole lot nicer than
<input type="text" data-bind="value: FirstName"/> <!-- Knockout -->
Loosey-Goosey
I’ve lost my strong typing, got back magic strings that have plagued the web since it’s inception (ugh) and I’m relying on a JavaScript field being there that may or may not exist!
This doesn’t make a whole lot of sense when you think about it though. I know that my WebAPI endpoint is serving up a “Person” type that has a FirstName. Similarly when I PUT or POST that person I know that the WebAPI endpoint is expecting that that property exist as well (or it’ll serialize as a null).
When you use a strongly typed, non-dynamic language like C# on your server you do so because it often just makes sense for enterprise software development. In a few words: the compiler is the cheapest tester you can have. Heck you don’t even have to write any unit tests to leverage the compiler.
JavaScript on the other hand is quite the opposite: but you gain the convenience of type coercion, functional, fully dynamic programming! (This all can be good and of course very bad…)
Bottom Line: using C# on the ‘server’ and JavaScript on the ‘client’ means you have made some sacrifices in both directions. My thought is why don’t we leverage the power of the compiler, strong typing, non-dynamic-ness that C# offers to the max when using Knockout.js and JavaScript.
An Answer?
This is where Fluent Knockout MVC Helpers attempts to bridge the gap in the least annoying way possible. How about this:
@{ var helper = Html.KnockoutHelperForType<Person>(); } <input type="text" @helper.DataBind(db => db.Value(x => x.FirstName)) /> <input type="text" @helper.DataBind(db => db.Value(x => x.LastName)) />
Above a Knockout helper is created for a particular type, in my case the JSON for the Person .NET type that I know is coming back from WebAPI. This allows the Knockout data-binds to be created in a refactor/compiler friendly, non-dynamic, manner. In this example (if observables were required) you would also want to use the ko.mappings plugin to create an equivalent observable for the .NET type’s JSON retrieved from WebAPI.
That’s about it for now. Take a look at the GitHub project I have created to build out this functionality demoed in a hopefully ‘non-trivial’ sample single page application for collecting surveys. Stay tuned!