This may be an unpopular answer, but I don't use ko.mapping
to translate my C# POCOs into JS viewmodels. Two reasons, really.
The first is a lack of control. ko.mapping will turn everything into an observable if you let it. This can result in a lot of overhead for fields that just don't need to be observable.
Second reason is about extensibility. Sure, ko.mapping may translate my C# POCOS into JS objects with observable properties. That's fine until the point you want a JS method, which at some point, you invariably will.
In a previous project, I was actually adding extra methods to ko.mapped objects programmatically. At that point, I questioned whether ko.mapping was really creating more problems than it solves.
I take on board your DRY concerns, but then, I have different domain-focused versions of my POCOs anyway. For example a MyProject.Users.User
object served up by a UserController might be very different from a MyProject.Articles.User
. The user in the Users namespace might contain a lot of stuff that is related to user administration. The User object in the Articles namespace might just be a simple lookup to indicate the author of an article. I don't see this approach as a violation of the DRY principle; rather a means of looking at the same concept in two different ways.
It's more upfront work, but it means I have problem-specific representations of User that do not pollute each others' implementations.
And so it is with Javascript view models. They are not C# POCOs. They're a specific take on a concept suited to a specific purpose; holding and operating on client side data. While ko.mapping
will initially give you what seems to be a productivity boost, I think it is better to hand-craft specific view-models designed for the client.
btw, I use exactly the same MVC3/KnockoutJS strategy as yourself.