在Web开发中,减少服务器的往返次数是提高页面响应速度的关键。本文将介绍一种方法,通过在客户端缓存数据,实现数据的本地过滤,从而避免不必要的服务器请求。
在MVC4与Razor视图引擎中,通常使用模型(Model)来传递数据至HTML页面。然而,一旦页面在服务器端渲染完成,模型对象就不再存在。因此,目标是在页面渲染时,将模型对象传递给一个全局的JavaScript变量。
JavaScript支持JSON格式,可以将模型对象转换为JSON格式,并存储在全局JavaScript变量中。然后,通过客户端代码,可以监听下拉框(combo box)的"onchange"事件,并执行必要的过滤操作以显示数据。这可以通过结合使用JQuery和JavaScript来实现。
在实现此功能之前,请确保项目中引用了System.Web.Helpers,并且确保属性中的"Copy Local"设置为true。
使用了一个数据模型来展示不同国家的不同"团队"。任务是构建一个网页,展示所有团队,并且能够展示特定国家的团队。使用以下模型来将信息传递给视图:
C# using System.Collections.Generic;
using System.Web.Mvc;
namespace NoRoundTrip.Models
{
public class IndexHomeModel
{
public IList Countries { get; set; }
public IList ListTeam { get; set; }
public string PageTitle { get; set; }
}
public class Team
{
public string TeamName { get; set; }
public string Country { get; set; }
}
}
实现此功能的第一步是创建一个控制器动作,返回视图中的模型对象,如下所示:
C# using System.Web.Mvc;
namespace NoRoundTrip.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
var model = MockDataLayer.DataLayer.GetTeamsInformationMock();
return View(model);
}
}
}
在这里,从数据源获取数据。在示例中,数据来自一个模拟源,它返回一个固定的列表以简化示例。
请注意,视图有一个参数,即给定的模型。
第二步是创建视图,在视图上,需要放置必要的元素来显示信息。Razor允许在视图中插入模型提供的值,如下所示:
C# @using System.Web.Mvc.Html
@model NoRoundTrip.Models.IndexHomeModel
@{
ViewBag.Title = Model.PageTitle;
}
@Scripts.Render("~/bundles/jquery")
@Model.PageTitle
@Html.DropDownList("combobox1", @Model.Countries)
在这里,可以看到一个填充了来自Countries列表的国家的下拉框控件。这个下拉框被命名为combobox1。这是为了在JavaScript中识别它。
另一个重要的事情是带有Id content的div标签。使用这个区域来嵌入JavaScript在页面加载时生成的代码。如所见,这一步没有生成下拉框结果的代码。
当页面准备发送到客户端时,服务器会生成一个page.ready事件。在那里,将模型转换为JSon字符串,并存储在全局JavaScript变量中:
JavaScript
<script type="text/javascript">
var jmodel;
</script>
<script type="text/javascript">
$(document).ready(function() {
jmodel = @Html.Raw(Json.Encode(Model));
$('#content').html(OrganizeContent(jmodel));
});
</script>
@Html.Raw(Json.Encode(Model));这行代码将模型转换为JSon,并存储在全局JavaScript变量jmodel中。这个变量在客户端可用,使用它来存储模型信息,并根据下拉框中选择的国家选择要显示的数据部分。
注意:Visual Studio 2012将@Html.Raw.(Json.Encode(Model));的结尾标记为语法错误,这是一个已知的VS错误。忽略它,项目应该可以无错误地编译。
最后一行jQuery代码将必要的HTML插入到带有id = content的标签中,以列出团队信息。
使用以下JavaScript代码格式化团队列表:
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;
}
var html = '';
for (var i = 0; i < list.length; i++) {
html += '' + list[i].TeamName + '';
}
html += '';
return html;
}
</script>
代码根据下拉框控件中显示的文本创建团队列表。也可以使用Value元素。在这种情况下,使用文本(注意,当对象Model被转换为JSon时,Text被转换为text)。
重要:请注意,模型的列表被转换为数组。
现在,作为最后一步,需要为客户端事件onchange创建一个处理JavaScript函数,这个函数简单地调用OrganizeContent,以更新下拉框中选定的项目,并重新绘制content标签内的代码。
JavaScript
<script type="text/javascript">
$(function() {
$('#combobox1').change(function() {
$('#content').html(OrganizeContent(jmodel));
});
});
</script>
就是这样。然后,将看到一个如图1所示的屏幕。
在这里,开发了一个页面,它使用从服务器传递的相同信息来显示过滤后的信息,而无需再次访问服务器。
如果需要显示的信息量不是特别大,或者如果开始显示信息时不使用过滤器(即下拉框中的"All"选项),这特别有用。