在 MVC 4 中捕获模型, 避免往返





5.00/5 (2投票s)
一个教程,
引言
本小型教程将为您提供避免往返服务器并获得更快页面响应的信息。
并非总是可行,但在某些情况下,我们可以避免不必要的往返服务器,并通过客户端代码来实现。一种典型情况是,我们有一个带有默认选项“全部”的组合框。在这种情况下,我们首次从服务器读取信息时,会将所有信息都获取到客户端。
这里的想法是将信息缓存在客户端的 JavaScript 全局变量中,并在此缓存信息上应用过滤器,从而避免去服务器获取过滤后的信息。
以下图片说明了此功能的一种典型用法
背景
使用 Razor 的 MVC 4 使用 Model Data 对象来传输用于渲染 HTML 页面的信息,但在页面在服务器上渲染后,Model
对象将不再存在。因此,我们的第一个目标是在页面在服务器上渲染时,将 Model
对象传递到一个全局 JavaScript 变量。
JavaScript 支持 JSON 格式,因此我们需要将模型转换为 JSON 模型,并将其存储在全局 JavaScript 变量中。然后,使用客户端代码,我们可以捕获组合框或列表框的“onchange
”事件,并执行必要的过滤操作来显示数据。我们使用 JQuery 和 JavaScript 的组合来实现此目的。
您可以下载简单的示例以更好地了解此过程。
Using the Code
System.Web.Helpers
添加为引用,并且非常重要的是,在属性中检查“复制本地”是否为 true
。为了演示此功能,我们使用了一个显示不同国家/地区不同“团队”的数据模型。我们的任务是构建一个网页,显示所有团队,并且还可以显示特定国家/地区的团队。我们使用以下模型来传递信息到视图。
重要提示:请注意,将用作组合框项目的国家/地区是作为 SelectListItem
的列表创建的。如果您想使用 HTML 帮助程序创建组合框,则应使用此类。
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; }
}
}
实现此功能的第一步是创建一个控制器操作,该操作在视图中返回一个 Model
对象,如以下代码所示
using System.Web.Mvc;
namespace NoRoundTrip.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
var model = MockDataLayer.DataLayer.GetTeamsInformationMock();
return View(model);
}
}
}
在这里,我们从数据源获取数据。在示例中,数据来自模拟源,为简单起见,它返回一个固定列表。
请注意,您的视图以给定的模型作为参数。
第二步是创建视图,使用 Visual Studio(在视图上单击鼠标右键,然后在菜单中选择创建视图)。
然后,我们需要在视图上放置显示信息的必要元素。Razor 允许您将 Model
提供的值插入到您的视图中,如以下代码所示
@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>
在这里,您可以观察到用来自 Countries
列表的 Countries
填充的组合框控件。此组合框名为 combobox1
。这使得它可以在 JavaScript 中识别。
另一个重要的事情是带有 Id
内容的 div
标签。我们使用此区域来嵌入 JavaScript 在页面加载时生成的代码。如您所见,在此步骤中,没有生成带有组合框结果的代码。
当页面准备好发送到客户端时,服务器会生成一个 page.ready
事件。在那里,我们将模型转换为 JSON string
并将其存储在一个全局 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>
语句 @Html.Raw(Json.Encode(Model));
将模型转换为 JSON 并将其存储在全局 JavaScript 变量 jmodel
中。此变量在客户端可访问,我们使用它来存储模型信息,并根据组合框选择的国家/地区选择要显示的数据部分。
注意:Visual Studio 2012 将 @Html.Raw.(Json.Encode(Model));
的结尾标记为语法错误,这是一个已知的 VS bug。忽略它,项目应该可以编译而不会出错。
最后一行 jQuery 代码将必要的 HTML 插入到 id = content
的标签中,以列出团队信息。
我们使用以下 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>
该代码根据组合框控件中显示的文本创建团队列表。您也可以使用 Value
元素。在本例中,我们使用文本(请注意,当 Model
对象转换为 JSON 时,Text
会转换为 text)。
重要提示:请注意,Model
的列表已转换为数组。
现在,作为最后一步,我们需要为组合框的客户端事件 onchange
创建一个处理 JavaScript 函数,该函数简单地调用 OrganizeContent
,以更新组合框选定的项目并重绘 content
标签内的代码。
<script type="text/javascript">
// This jquery function is triggered when the combo box changes text.
$(function () {
$('#combobox1').change(function() {
$('#content').html(OrganizeContent(jmodel));
});
});
</script>
就这样。然后,您将看到如图 1 所示的屏幕。
关注点
在这里,我们开发了一个页面,该页面使用从服务器传递的相同信息来显示过滤后的信息,而无需再次访问服务器。
这在要显示的信息量不是特别大,或者您一开始就显示信息而不使用过滤器(即组合框中的“全部”选项)时特别有用。
如果信息量非常大,您应该考虑将所有信息传递到客户端所需的时间延迟,而不是通过往返服务器来传递部分信息。
历史
- 第一版