Question

What we usually see in framework documentations are simple blog-like applications where each page is related to only one model and one controller.

How to deal with the most common case where a single page have to display information from different models?

Example:

A social network home page that shows:

  • Recent user posts
  • Recent users
  • News from the admins
  • Most played games

Is this supposed to be handled by a single controller that loads all this information from the different models and send it to a view that is potentially broken down into partials / elements?

Someone said in another question that I could create something like a HomePageController for pages like this. What if all that information should be displayed in the sidebar for all pages on the site, how do I handle that?

Was it helpful?

Solution

Typically, you'll collect all the different kinds of data and pass it to the view together:

MVC frameworks generally provide some way to map request URLs (e.g. /offers?id=5) to controllers (or their methods).

Let's assume that you want to display some data on your homepage.
To do this, you'll first define mapping from URL /home to some particular controller, let's say HomePageController. Using your example data, you'll have something like this in your controller (in method that will handle request):

model.add(dao.getRecentUserPosts());
model.add(dao.getRecentUsers());
model.add(dao.getNewsFromAdmins());
model.add(dao.getMostPlayedGames());

render("viewName", model);

Upon request to some adress mapped to this specific controller, you will get different kinds of data from your Data Access Object (dao), and the add them to your model.
Once model is filled with data, you can pass it to a view ( = render view with this model), and in view you'll display it any way you want to.

I hope that basic flow is now clear to you.

Referring to @BeK's answer:
handling requests that take longer will always need an individual approach. You may choose to load this part asynchronously, you may (and probably will) try to cache as much as you can.

Loading the sidebar:
most of MVC frameworks provide some kind of 'base template' for your view.
That means you can define one part of view (e.g siderbar or footer) that is displayed on every page, and in particular controllers you only care about the dynamic parts. Those solutions are flexible enough to satisfy most of the typical needs.
There are a lot of options depending on what are you displaying in that sidebar - is it static or dynamic? what can be cached? etc.

OTHER TIPS

There are several options here. It really depends on what kind of data you are loading. If one of the data requests takes a long time the view will not be displayed until all the data is gathered. If you break the view down in partials and let them load async, the user will have a better UX. In this way you can have the separate controllers/controller methods, complying with patterns like SRP.

If you want all the data to be displayed in the sidebar of every page, than maybe one controller taking care of it will be an easier solution, but again I would suggest take a look at the data you are loading and especially the time it takes to load all the data. Hope this answers your question or sets you on the right path.

alternate approach to follow SRP is using MVC child actions.

create many models and controller. each controller responsible for its own business logic eg.

  • PostsController
  • NewsController
  • GamesController
  • HomeController

starting from HomeController that render the HomePage.cshtml

<div>@Html.Partial("Login.cshtml", Model.CurrentUser)</div>
<div>
    <hgroup>
        <h2>what's new</h2>
    </hgroup>
    <div>@Html.Action("WhatNew", "News")</div>
    <div>@Html.Action("RecentlyPosted", "Posts")</div>
</div>
<aside>
    <h2>Games</h2>
    <div>@Html.Action("MostPlayed", "Games")</div>
</aside>

you may fetch list of many controller/actions name as string in HomeController then render multiple child actions in main page.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top