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)
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 !
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.
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.
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.
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.
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") %> +
<%= Html.TextBox("y") %> =
<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());
}
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).
Related
We're actually planning a really complex web application. At least for my own standards.
In the past we have always been using a combination of a server side MVC Framework (Codeigniter) and client side functionality (jQuery and plugins). We have simply written inline javascript code in our views. This worked as expected, but of course with several disadvantages:
no caching
duplicated js code
maintainability issues
...
My main goal now is to organize the client side code in an efficient and easily maintainable way. But I want to stay with the server side MVC because of the existing know how and some existing interfaces. Furthermore I want to reduce complex DOM manipulation with jQuery and "spaghetti code".
Now I thought about a combination of Backbone.js and Require.js but I really can't find a tutorial or any solid description about how to combine them with a server side MVC.
Is it even recommended?
In my old apps I got a file structure like this:
application (CodeIgniter)
assets
js
css
imgs
Are there any ideas or best practices?
Thank you!
To add to mexique1's advice, it might be worth looking at the backbone-boilerplate project. It should provide you best-practice solutions for many of the problems you're currently considering, such as the combination of require and backbone, the organisation of the client-side of your project, and the reduction of complex DOM manipulation (see templating).
The challenge, as you anticipate, will most likely be in combining the boilerplate approach with the approach you're used to. However, it will almost certainly be worth the effort since it should provide you a solid foundation for this and future projects.
I think Backbone is a good choice, and Require is not mandatory here.
Require will just help you organize your source code and maybe improve performance. I think you can start right away with Backbone, which will be the thing you are going to use most, and add Require later.
Regarding Backbone, yes it's easy to use to use its Model with an existing MVC application, provided it returns JSON. To load your existing data you will want to use the fetch method combined to url to adapt to your existing code, or your own method.
Generally, think about which models are displayed in which views. Backbone helps you think this way : I'm displaying Models represented as JSON data in Views which are made by HTML.
Also, for the view layer, it's very easy to reuse your existing HTML, because views are not tied to anything, no JavaScript templating or nothing.
Simple example :
<div id="user">
<span class="name">John</span>
</div>
var UserView = Backbone.View.extend({
render: function() {
this.$el('.name').html(this.model.get('name'));
}
});
var userView = new UserView({el: $('#user')[0], model: ...});
In this example the #user div reflects the state of a User model, with its name.
Also check the Todo App example in Backbone.
Today when I searched on the internet I saw the View first approach in web development of Lift framework. Can somebody tell me the differences between view first and MVC approach ?
Thank you very much
View first is based not on a model and a controller, but mostly interested in the view. Many problem domains do not neatly compose in controllers and models. Think about a ecommerce site, the shopping cart exists on all pages, but should every controller control it? Personally in MVC too much of my time is spent thinking about how to logically make the problem fit into MVC than just coding. View first takes away this controller / view / model and instead just has a view which in Lift can call "snippets". It is almost a superset of MVC since if you wanted you could only have a single snippet per page, but Lift allows you to do much more. Snippets can be cross cutting concerns or very page specfic logic.
From the lift website..
Lift is different [from MVC]. For HTML requests, Lift loads the view first and builds your page from the view. Lift also supports REST style requests for non-HTML data. (See 11 on page 1↑) “Why?” Because complex HTML pages rarely contain a dominant piece of logic... a single controller... but contain many different components. Some of those components interact and some do not. In Lift, you define the collection of components to be rendered in the resulting HTML page in the view.
When your using lift, you basically have a view(page) and from this you could incorporate any snippet(app) that you have without much of the antics you'd normally have to do in an MVC framework/environment.
Basically you don't have to choose what the most important thing on the page is just what you want to add to a page and then add it.
I have been developing MVC 3 applications using Razor. I was wondering how much code would be acceptable in my views. There were situation where I needed to create, instantiate and use an object which wasn't included in the model and using ViewModel would make the model object bloated. Now when I look at some of my views, I find them full of server side codes. What would be the best practice when dealing with such issues?
I was wondering how much code would be acceptable in my views.
If by code you mean C# code then there should be exactly 0 to be precise. On the other hand it is perfectly fine to write HTML markup in your views and call HTML helpers.
There were situation where I needed to create, instantiate and use an
object which wasn't included in the model and using ViewModel would
make the model object bloated
Then it seems that your view model was not adapted to this view (since this view requires additional information). So change this situation by adapting the view model to it and including everything that it needs.
Now when I look at some of my views, I find them full of server side
codes. What would be the best practice when dealing with such issues?
Yes, that's horrible. Simply adapt your view models and refactor this code into your view models or controllers or even write custom HTML helpers.
I am writing a helper class to query my Zenfolio feed, return and display the images. Right now this code is split between a viewmodel and code in my controller. I want to pack it up into a helper class. Would all the code go into the helper or do i still split the code among different class with the helper only responible for generating the html? I have googled but not found an answer to my question.
Within the MVC pattern there is a clear separation between Model (data), View (html) and Controller (what gives the Model to the View).
To answer your question, No. Load your models in your Controller. Display them in your View. Html Helpers should only generate html for your view.
You may want to consider using a DisplayTemplate, which allows you use the same View template for every model of a particular type.
I wouldn't do any data access from the view. This sounds like a good use case for an action, and reusing code via the RenderAction method. You can mark the action as a child action using the [ChildActionOnly] attribute, which ensures it can't be invoked directly from the HTTP request, and return a PartialView result.
HTML helpers should really be used to generate HTML tags from data taken from the ViewData or Model (i.e. your view model in this case).
Data access in an HtmlHelper is only pain.
I've had the misfortune to inherit a project that had ad-hoc SQL placed into the HtmlHelpers by the 2nd developer on a project. The HtmlHelpers were beautifully written by the first developer, and the ad-hoc SQL pretty much nullified all of the time and effort put into having an service oriented architecture, having an ORM (the 2nd level cache became worthless), the unit of work pattern(transactions, worthless), and every aspect of design. Eventually, this 2nd developer had to make larger and larger HtmlHelpers so that different elements could share access to the data.
This was originally done for a display mode, and editing was accomplished through a pile of ugly custom javascript. All told, when the page rendered, it made 600 synchronous calls to the database.
I understand what is MVC and CMS. I understand MVC pattern and how CMS should working. But I have problem with theming and the pattern.
Example:
When CMS is installed on serwer I want to change my homepage. I want to display some additional data. I change my homepage template and add a function call to pull data from DB. My new data will be displayed on my homepage. :)
But when I do this I broke MVC pattern because in this situation View decide which data should be read from DB to display on my homepage.
So... is it MVC for a CMS? Or maybe it shouldn't be a clear MVC pattern to work with situations like this? Maybe I should forget about patterns? I'm confusing...
PS
Wordpress it's not build on MVC pattern, I guess?
Design patterns like MVC are meant to be about separating your display code from the business logic, etc. This makes it easier to change any part without affecting any of the other parts (eg. change the templates without having to worry about accidentally changing any business logic).
You situation sounds like the function you are adding is simple view logic? It might be best to put the function into a Helper and have the helper call for the data through a Model. Then, in your view, just call the Helper.
In pseudocode:
Helper
function get_whatever_data () {
// get the actual data from the model
return SomeModel.get_the_data_thats_needed_here()
}
View
<div id="some-id">
<? print get_whatever_data() ?>
</div>