Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Avoid Round Trip by Catching your Model in MVC 4

5.00/5 (2 votes)
6 Jun 2013CPOL5 min read 26.8K   195  
A tutorial to catch the Model in your client side and use client events to show filtered information without returning to server

Introduction

This small tutorial will give you the information to avoid round trip to server and get a faster response of your pages.

It is not always possible, but in some cases, we can avoid an unnecessary round trip to the server and give, via client code. A typical situation is when we have a combo box with the option of "All" as default, in this case the first time that we read the information from the server, we got all the information to the client.

The idea here, is cache the information in the client in a JavaScript global variable, and apply the filter over this cached information avoiding going to the server to get filtered information.

The following pictures illustrated a typical usage of this:

Image 1

Background

MVC 4 with Razor uses a Model Data object to transmit information to be used in the render HTML page, but after the page is rendered in the server, the Model object does not exist more. Then, our first goal is to pass the Model object to a global JavaScript variable when the page is rendered in the server.

JavaScript supports JSON format, then we need to convert the model to a JSON model, and store it in a global JavaScript variable. Then, using client code, we can catch the "onchange" event of the combo box or list box, and make the necessary filter operation to show the data. We make this using a combination of JQuery with JavaScript.

You can download the simple example to get a better idea about the process.

Using the Code

Important: If you use this code in your project, be sure that you have System.Web.Helpers as reference, and very important, see in properties if "Copy Local" is true.

To demonstrate this feature, we used a data model that show different "team" from different countries. Out task is to construct a web page that shows all teams and also can show the teams of a particular country. We use the following model to carry the information to the View.

Important: Note that Countries that will be used as items in the combo box, are created as a List of SelectListItem. You should to use this class if you want to use the HTML helper to create a combo box.

C#
using System.Collections.Generic;
using System.Web.Mvc;

namespace NoRoundTrip.Models
{
    /// <summary>
    /// Model for Index - Model action.
    /// </summary>
    public class IndexHomeModel
    {
        /// <summary>
        /// List of all countries.
        /// </summary>
        public IList<SelectListItem> Countries { get; set; }

        /// <summary>
        /// List of all team of all countries
        /// </summary>
        public IList<Team> ListTeam { get; set; }

        /// <summary>
        /// Page Title.
        /// </summary>
        public string PageTitle { get; set; }
    }

    public class Team
    {
        public string TeamName { get; set; }
        public string Country { get; set; }
    }
}

The first step to implement this feature is to create an action in a controller that returns a Model object in the view, as is shown in the following code:

C#
using System.Web.Mvc;

namespace NoRoundTrip.Controllers
{
    public class HomeController : Controller
    {
         public ActionResult Index()
        {
           var model = MockDataLayer.DataLayer.GetTeamsInformationMock();
           return View(model);
        }
    }
}

Here, we get the data from our data source. In the example, the data comes from a mock source that return a fixed list for simplicity.

Observe that your View has as parameter, the given model.

The second step is create the View, use the Visual Studio (click with right button over the View and select in menu create View).

Over the view, then we need to place the necessary element to display the information. Razor gives you the opportunity to insert in your View the values given by the Model as you can see in the following code:

C#
@using System.Web.Mvc.Html
@model NoRoundTrip.Models.IndexHomeModel
@{
    ViewBag.Title = Model.PageTitle;
}
@Scripts.Render("~/bundles/jquery")
<div class="Center-Text">
    <h2>@Model.PageTitle</h2>
    @Html.DropDownList("combobox1", @Model.Countries)

    <div id="content">
    </div>
</div>

Here, you can observe the combobox control that is filled with the Countries that comes from the Countries list. This Combo box is named combobox1. This possibility is to identify it in JavaScript.

The other important thing here is the div tag with the Id content. We use this area to incrust the code generated by JavaScript when the page is loaded. As you can see, no code with the result of the combo box is generated in this step.

When the page is ready to be sent to the client, a page.ready event is generated in the server. There, we made the conversion of our Model to a JSon string and store it in a global JavaScript variable:

JavaScript
<script type="text/javascript">
    // This global variable is used to store the json representation of model in the client.
    var jmodel;
</script>

<script type="text/javascript">
    $(document).ready(function () {
         jmodel = @Html.Raw(Json.Encode(Model));
        $('#content').html(OrganizeContent(jmodel));
    });
</script>

The sentence @Html.Raw(Json.Encode(Model)); converts the model in JSon and stores it in the global JavaScript variable jmodel. This variable is accessible in client side and we use it to store the model information and select the portion of data to display based in the country selected by the combo box.

Note: Visual Studio 2012 marks as syntax error the end of @Html.Raw.(Json.Encode(Model)); this is a known bug in VS. Ignore it, the project should compile without error.

The last jQuery code line, insert in the tag with id = content the HTML necessary to list the teams information.

We use as example the following JavaScript code to format the Team list:

JavaScript
<script type="text/javascript">
function OrganizeContent(mod) {
     var list = [];
     var e = document.getElementById("combobox1");
     var indexselected = e.options[e.selectedIndex].text;
     if (indexselected != "All") {
        for (x in mod.ListTeam) {
            var item = mod.ListTeam[x];
            if (item.Country == indexselected) {
               list.push(item);
            }
        }
    } else {
       list = mod.ListTeam;
    }

    // Create the html to be show
    var html = '<div id= "table"><p></p>';
    for (var i = 0; i < list.length; i++) {
        html += '<div>' + list[i].TeamName + '</div>';
    }

    html += '<div>';
    return html;
}
</script>

The code creates a list of Teams based in the text showed in the combo box control. You can also use the Value element. In this case, we use text (observe that when the object Model is translated to JSon, Text is converted in text).

Important: Observe that the lists of the Model are transformed in arrays.

Now, as a last step, we need to create a handle JavaScript function to the client event onchange of the combo box, this function simply calls OrganizeContent, to update the combo box selected item and redraw the code inside the content tag.

JavaScript
<script type="text/javascript">
    // This jquery function is triggered when the combo box changes text.
    $(function () {
        $('#combobox1').change(function() {
            $('#content').html(OrganizeContent(jmodel));
        });
    });
</script>

That is all. Then, you have a screen as shown in figure 1.

Points of Interest

Here, we have developed a page that uses the same passed information from server to show filtered information without the necessity to go to the server again.

This is particularly useful if the quantity of information to show is not particularly heavy to transport, or if you begin to show the information without using filters, that is the option All in combo box.

If the quantity of the information is very heavy, you should consider the delay time to pass all the information to the client again to pass part of information using round trip to server.

History

  • First version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)