tags:

views:

821

answers:

7

I'm a bit confused about how MVC works and I can't find anything but basic examples.

I want to make a kind of widget-based design; you can choose various widgets to go on your page. Each widget should be responsible for itself - it should have a controller and a view. But what about the main page? Suddenly I've got a page with lots of controllers on it!

The obvious thing to do is to embed the controllers in the view somehow... This is my widget {SomeWidget} but I've read that "breaks the MVC paradigm".

Some widgets will need to POST to different urls (like a search box goes to the result page) and some will need to POST back to the same URL (like adding a comment to an article brings you back to the article).

To top things off, the user should be able to edit the HTML around the widget - for example if they want a search box on the right, they can type <div style="float: right;">{SearchController}</div> (in my paradigm-breaking world)

+2  A: 

I am not very good at web programming, but i believe, from the example you described, that there should be one model, one view and one controller for the entire page. Now the view itself should contain the views for every widget in the page (and the same goes for the page controller) to which it dispatches the messages it receives.

Conceptually there is a lower level of MVC (for widgets) and a higher level of MVC (for the page). And the MVC paradigm won't be broken. Now you can edit the HTML around the widget, it changes the page model (and not any widget model).

Hope this helps !

Benoît
Having to add code to the template and the class doesn't make for a plug and play widget.
rick
I am afraid i don't understand your comment... Could you rephrase ?
Benoît
+2  A: 

To add to @Benoît's comment:

The Symfony framework handles this with components. Each component is a self-contained MVC instance that can be embedded into another view. It cannot be instantiated to respond directly to web requests like the normal MVC instance (a module/action pair). It can only be embedded into another MVC view.

As a side note: Symfony also treats plugins as their own complete MVC instance, complete with its own schema, models, controllers, config files, views, et al.

In your case, each component would be its own MVC instance and the app would stitch these components together. Each component would be responsible for how it responds to a form submit.

MVC doesn't mean there is ONE view and ONE controller. It just means the app logic is stored in models, the controller glues things together, and the view builds the display. It's a formal and logical separation of logic and presentation.

jcoby
A: 

There are a lot of variations on the MVC theme and a lot to consider before coming to a conclusion as to the design of your particular system. Most of the latest, popular web based systems look to IoC as the guiding principal. Usually, some kind of framework component is the controller that uses some kind of configuration to invoke the proper template as the view and to couple it with the appropriate object hierarchy as the model. Most of these systems include an extensible GUI widget library to be used by the templates. You can add your own widgets but it is not best practice to hard code your widgets to a specific object hierarchy. That IoC link also talks about components and services which should give you some direction on how to avoid that hard coding.

Glenn
+1  A: 

One of the best, short, and simple books I have found on MVC is this one handed out last week at the PDC 2008 expo:

http://www.apress.com/book/view/1430216468

Not only does it cover MVC's concept, but its comparisons to other concepts such as Ruby on Rails and MVP methodology.

In addition, it goes into the entire reason MVC exists by describing it's seperation of concerns, and why it should not only be at the UI level - but down into your actual layers or IoC structure of your business objects and DAL.

I'd highly recommend this book as he covers best practices, in just 110 pages or so.

And no, I do not work for FirstPress or related to them at all. I just liked the book, and finally someone I agree with.

This book is more about a specific MVC Framework (ASP.NET MVC). However, I do at least agree that it has a nice section on how MVC compares with other user interface patterns.
Greg Malcolm
A: 

ASP.NET MVC is well suited for a widget dashboard mashup type page.

Take a look at this session from PDC 2008.

You will probably want to use the Ajax helpers to update the islands of data in each widget. Here is a snippet of how you could put a calculator on any page but keep the code independent.

View Snippet:

<script type="text/javascript">
    function OnFailure(error) {
        alert("We have encounterd an error " + error);
    }
</script>
<% using (Ajax.BeginForm("Add", new AjaxOptions{UpdateTargetId="sum", OnFailure="OnFailure"})){ %>
    <%= Html.TextBox("x") %>&nbsp;+&nbsp;
    <%= Html.TextBox("y") %>&nbsp;=&nbsp;
    <span id="sum">?</span>
    <input type="submit" value="AddEm" />
<% } %>

Controller Snippet:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Add(string x, string y)
{
    int sum = int.Parse(x) + int.Parse(y);       
    return Content(sum.ToString());
}
Jamey McElveen
Why was this answer voted down? If there is an error let me know and I will correct.
Jamey McElveen
+1  A: 

The best information I've found on doing widgets in ASP.NET MVC is on Steve Sanderson's blog. He explains his concept of partial requests which is a different technique than sub-controllers.

http://blog.codeville.net/2008/10/14/partial-requests-in-aspnet-mvc/

Partial Requests are easy You’ve heard of partial views, so how about partial requests? Within any MVC request, you can set up a collection of internal partial requests, each of which can set up its own internal partial requests and so on. Each partial request renders a plain old action method in any of your plain regular controllers, and each can produce an independent widget. I’m calling them partial “requests” rather than “controllers” because they run a proper MVC request-handling pipeline that’s compatible with your routing system and your controller factory. Still, as with subcontrollers, all the control remains in controllers, and the view can be ignorant.

JarrettV
A: 

I think JarrettV's and jcoby's answers are closest.

I've come to know subcontrollers as Hierarchical MCV (HMVC). The idea is that you "pull" content (a view populated by a subcontroller) from the parent view template instead of "pushing" data to the template from the controller. So instead of needing to edit both the controller and view to add a widget, you just call the widget from the view. There are libraries to accomplish this in the php frameworks CodeIgniter (Modular Extensions) and Kohana (Dispatch, and Component).

rick