Design – How to handle complex views (consisting of several parts) in MVC web application

Architecturedesigndesign-patternsuiweb-applications

Lets say I am writing a blog web application using MVC pattern. Typical layout for the main page of the blog application is – some kind of a post index in the main part, and aside there are some addition parts, like timeline, tag navigation panel, subscribing panel, etc. Those controls also appear on a single post view, and may appear on other views I have.

My question is – how should I handle those panels aside in my views and controllers. I see three approaches here:

  1. Create a big viewmodel class that contains all the information
    required for rendering the view s (either index or single post).
    That case I could make these aside panels a partial views, and
    calling them from the view being rendered passing part of that big
    viewmodel. The drawback is – I will have the code filling viewmodel
    spread amongst various controller method, meaning code is
    duplicated. Which is quite bad.

  2. Create another layer of view rendering. Say, the topmost layer of
    rendering recives a alreay rendered parts of html, or functions
    which when called outputs an html. The layer under this "combining
    partials layer" would give just partial views for each panel I want,
    include main content. The drawback here – memory usage. Most modern frameworks renders htmls directly to output stream, but in this approach partial views would be rendered into string objects first – which leads to memory overhead.

  3. Use something like "RenderAction" from asp.net mvc, which calls a
    controller method from a view. I think this is a worst solution of 3
    given, because it drops an MVC approach.

The question is not tied to any specific framework, I want to understand the general way of doing things like that.

UPDATE

After an answer given, I've found out that post is not clear. So reasonable update here:

Under viewmodel term I understand an object that contains all the data required to render a particular view.

All of three approaches involve building partial views with their own viewmodel. For example (using C# syntax):

class SinglePostViewModel {
  string Text {get;set;}
  string Title {get;set;}
  string Slug {get;set;}
  DateTime PublishedDate {get;set;}
  ...
}

class TagNavigationPanelViewModel {
  string TagText {get;set;}
  int PostsCount {get;set;}
}

class CalendarNavigationPanelViewModel {
  DateTime YearAndMonth {get;set;}
  int PostsCount {get;set;} 
}

My question is – how to nicely combine those partial views together.

Best Answer

I see another method that, unless I've misunderstood your post, hasn't been mentioned:

The main view, post, would have its model. This model would consist of ONLY the properties necessary to display this post (author,title,body, etc). Then, every piece of the post view that you can think of (timeline, tag navigation panel, subscribing panel, etc), would be split into their own views and each one would have its own model. This way, you can build up those models in your controller when you need them.

It might sound like an unnecessary amount of extra work to split these out like this, but it lends itself to the single responsibility principle. Keep each "view/model" focused on itself so that it can be re-used anywhere it is needed.

If you feel that your code is beginning to duplicate itself, which it might depending on your situation, you should consider writing some sort of "helper class." This helper class would handle all of the model build-up in one place, and all other duplicate code would be stripped down to a helper class call.