18

does it make sense to use KnockoutJS Viewmodels in combination with ASP.NET MVC3 or 4? Because it is not very DRY, isn't it? I have to write models for EF, Viewmodels for the MVC Views and Viewmodels for Knockout... and i lose a lot of magic. Automatic client-side validations for example.

Does it make sense to use MVC at all if one sticks with the MVVM Pattern?

Cocowalla
  • 13,822
  • 6
  • 66
  • 112
Matze-Berlin
  • 197
  • 1
  • 5
  • By using Knockout you're exchanging one bit of 'magic' for another (e.g. automatic updating of UI properties etc) – Steve Greatrex Mar 23 '12 at 12:24
  • Steve, yes i know and i like the Knockout "magic". which way would you go? say with a medium sized web application with lots of forms and validations? – Matze-Berlin Mar 23 '12 at 12:27
  • 3
    Why not mix and match - use MVC to generate your forms, use unobtrusive validation to handle client-side validation, and just use knockout when you want to do something more interactive client-side? – Steve Greatrex Mar 23 '12 at 12:33
  • 1
    Most of the projects on which I have used knockout have been fairly small scale though – Steve Greatrex Mar 23 '12 at 12:34
  • 1
    there is a solution on this link: http://stackoverflow.com/questions/5741658/knockout-mvc-3-validation/6559734#6559734 –  Apr 20 '12 at 18:12

5 Answers5

15

With Knockout Mapping, you can automatically generate a KO view model from your MVC view model.

This is a proper pattern: your models are raw entities, your data. Your views are the UI. And your view models are your models adapted to that specific view.

Judah Gabriel Himango
  • 58,906
  • 38
  • 158
  • 212
  • 3
    It makes perfect sense, this is the approach that I use. MVC4 ships with Knockout, I'm hoping there are some templates for using Knockout binding (especially with the new SPI stuff) – Joel Cochran Mar 23 '12 at 19:34
7

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.

Paul Alan Taylor
  • 10,474
  • 1
  • 26
  • 42
3

We use knockout Mapping to generate the KO view models well.

We have a business layer in a separate project that does CRUD, reporting, caching, and some extra "business logic". We aren't going to be using EF, or something similar. Currently we've defined c# classes as MVC models, and our controllers call the business layer to construct the Models that are defined in the usual place in our MVC app. These C# models get serialized as JSON for use in our pages.

Since everything we do in the browser is c#/JSON based using knockout, we aren't using MVC models in the traditional MVC way - everything gets posted as JSON and serialized to c#, so we don't use MVC model binding, validation, etc. We're considering moving these models to our business layer so they can be tested independently of the web app.

Se we'll be left with an MVC app that has controllers and views, but no models - controllers will get models that are defined in the business layer. We're nervous about departing from the normal MVC structure, but a KO/javascript based client is fundamentally different from a DOM based client that MVC was originally built around.

Does this sound like a viable way to go?

Petrus Theron
  • 27,855
  • 36
  • 153
  • 287
Old Man
  • 3,295
  • 5
  • 23
  • 22
  • I don't see any reason to throw away models just because you're going to a KO/javascript client. It still provides you binding when you post back and often you will want to display data on your first render even if you are using KO. Personally I would mix and match as appropriate. – Trevor de Koekkoek Jan 20 '13 at 10:50
1

I work now on project which mixes MVC3 and knockouts and I have to tell you - it's a mess... IMO it's nonsense to force some patterns just to be up to date with trend.

Zulu Z
  • 1,103
  • 5
  • 14
  • 27
1

This is an old topic, but now in 2014 (unfortunately) I still feel this question has a huge relevance.

I'm currently working on a project which mixes MVC4 with knockoutjs. I had some difficoulties to find whichs part should be handled on which side. Also, we needed a "SPA-ish" kind of architecture, where each module has its own page, but then inside that module there is only AJAX interaction. Also faced some heavy validation scenarios, and needed to provide user (and SEO) friendly URLs inside each module. I ended up with the following concept, which seems to be working well:

Basic MVC and .NET side roles:

  • Handling authentication and other security stuff.
  • Implementing the Web API interface for the client-side calls (setting up viewmodels, retrieving and mapping data from the domain, etc.)
  • Generating knockout viewmodels from my (pre-existing) C# viewmodels with T4 templates, also including knockout validation plugin extensions from .NET validation attributes. (This was inspired by this aticle). The generated viewmodels are easily extensible, and the generation can be finetuned with several "data annotation"-like custom or built-in attributes (such as DefaultValue, Browsable, DataType, DisplayFormat, etc.). This way the DRY doesn't get violated (too much).
  • Providing strongly typed, but data-independent partial view templates for each submodule (each knockout viewmodel). Because property names on C# viewmodels are same as in KO models, I can benefit from the strongly typed helpers specifically written for KO bindings, etc.
  • Providing the main view for each module similarly to previous point.
  • Bundling and minification of all scripts and stylesheets.

Basic client-side roles:

  • Loading the initial state of all viewmodels encapsulated into one module page, taking the whole URL into account with a simple route parser implementation.
  • Handling history with history.js
  • Data-binding, user interaction handling.
  • Posting relevant parts of viewmodels to the server, and processing the returned data (usually updating some viewmodel with it).

I hope this could help anyone else who feels lost in the world of trendy technologies. Please, if anyone has any thought on this, feel free to post any question or suggestion in the comments.

Zoltán Tamási
  • 12,249
  • 8
  • 65
  • 93