Thursday, March 8, 2012

MVC4 Single Page Basics

I recently highlighted that I had a bit of an issue with the MVC4 tutorials that are available here as I do not believe the standard application structure for the default apps is adequately documented.

I also note that there are some unnecessary differences between the base templates that can further confuse the issue, predominantly in the View definitions, that make it difficult to discern the important differences between the template types e.g. Single Page Applications / Mobile applications / Web API.

For example, the Login.cshtml Header in the mobile template is defined as
@section Header {
    @Html.ActionLink("Cancel", "Index", "Home", null, new { data_icon = "arrow-l", data_rel = "back" })
    <h1>@ViewBag.Title</h1>
}

while in the SPA application it is defined as
<hgroup class="title">
    <h1>@ViewBag.Title.</h1>
    <h2>Enter your user name and password below.</h2>
</hgroup>

Now there is a realistic need for the actions to be defined in the mobile header and not in the SPA header, BUT I think the differing use of hgroup and @section Header should have been standardised.



As for a lack of basic plumbing documentation, I think the SPA application is very lacking in this area. The tutorials are very good at showing how the data access and data binding works, but one thing that really stood out for me was the lack of information on how the login page was loaded in a popup and how the actions were resolved as Ajax actions instead of standard actions.

Looking into the code it wasn't actually that difficult to identify where things were happening, for example the line
        <script src="@System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script>

in the _layout file loads all the javascript code in the scripts folder, which in turn loaded the AjaxLogin script file.
The code below then overrides the onclick of the login links to render the link content in a popup instead of a new page.
// List of link ids to have an ajax dialog
    var links = ['#loginLink', '#registerLink'];

    $.each(links, function (i, id) {
        $(id).click(function (e) {
            var link = $(this),
                url = link.attr('href');

            if (!dialogs[id]) {
                loadAndShowDialog(id, link, url);
            } else {
                dialogs[id].dialog('open');
            }

            // Prevent the normal behavior since we use a dialog
            e.preventDefault();
        });
    });

The loadDialog function sets an additional query parameter (content=1) which the Controller accepts and renders a PartialView instead of a View (in ContextDependentView(), and prefixes "Json" to the action property in the ViewBag. The View itself uses this 'action property' as the post action, which ensures that the correct Action is called (either JsonAction or just Action) is called on the HttpPost for the View.

Yes once you know what is going on it is easy to follow, but all this detail is very important to the way Single Page Applications work, as much if not moreso than how to use upshot and knockout, and it is just left to developer to figure it out.

Anyway, this is Beta, but I just thought that for something so central to the development experience with Mvc4 there should be more emphasis on the basics to ensure that people understand what is happening rather than just guiding them directly to loading data.

No comments:

Post a Comment