基本准备
首先,新建一个ASP.NET MVC 3的空项目。
然后新增一个Model,代码如下:
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Web; namespace MVCApplication.Models { public class Appointment { public string ClientName { get; set; } [DataType(DataType.Date)] public DateTime Date { get; set; } public bool TermAccepted { get; set; } } }
接着是新增一个Controller,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MVCApplication.Models; namespace MVCApplication.Controllers { public class AppointmentController : Controller { // // GET: /Appointment/ public ActionResult Index() { return View(); } [HttpPost] public ActionResult Index(string id) { return View("Index", (object)id); } public ViewResult AppointmentData(string id) { IEnumerable<Appointment> data = new[] { new Appointment{ClientName="Joe", Date = DateTime.Parse("1/1/2012")}, new Appointment{ClientName="Joe", Date = DateTime.Parse("2/1/2012")}, new Appointment{ClientName="Joe", Date = DateTime.Parse("3/1/2012")}, new Appointment{ClientName="Jane", Date = DateTime.Parse("1/20/2012")}, new Appointment{ClientName="Jane", Date = DateTime.Parse("1/22/2012")}, new Appointment{ClientName="Bob", Date = DateTime.Parse("2/25/2012")}, new Appointment{ClientName="Bob", Date = DateTime.Parse("2/25/2013")} }; if(!string.IsNullOrEmpty(id) && id != "All") { data = data.Where(e => e.ClientName == id); } return View(data); } } }
最后是新增两个View,分别如下。
Index.cshtml:
@model string @{ ViewBag.Title = "Index"; } <h4>Appointment List</h4> @using (Html.BeginForm()) { <table> <thead> <th>Client Name</th> <th>Appointment Date</th> </thead> <tbody id="tabledata"> @Html.Action("AppointmentData", new { id = Model}) </tbody> </table> <p> @Html.DropDownList("id", new SelectList(new[] {"All", "Joe", "Jane", "Bob"}, (Model ?? "All"))) <input type="submit" value="Sumbit" /> </p> }
AppointmentData.cshtml:
@using MVCApplication.Models @model IEnumerable<MVCApplication.Models.Appointment> @{ Layout = null; } @foreach (Appointment appt in Model) { <tr> <td>@Html.DisplayFor(m => appt.ClientName)</td> <td>@Html.DisplayFor(m => appt.Date)</td> </tr> }
其中,AppointmentData.cshtml是作为一个partialview的。
这样,当点击按钮时,页面回送给服务器,根据用户所选择的选项显示相应数据。
启用AJAX
为了启用AJAX,需要在Web.config中新增一行配置,如下:
<configuration> <appSettings> <add key="ClientValidationEnabled" value="true"/> <add key="UnobtrusiveJavaScriptEnabled" value="true"/> </appSettings> ... </configuration>
这里有两个配置,第一个是启用客户端验证的,它依赖于第二个配置。第二个配置就是启用AJAX的。
页面上为了引用AJAX,需要引用一个AJAX文件,可以加在模板页中,如下:
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-Ajax.js")" type="text/javascript"></script>
接下来还要做两个工作。
第一,定义一个AjaxOptions,这个里面有很多配置,目前先只使用UpdateTargetId,它定义要替换的目标。
第二,将Html.BeginForm()替换为Ajax.BeginForm("AppointmentData", ajaxOpts)。
修改后的Index.cshtml如下:
@model string @{ ViewBag.Title = "Index"; AjaxOptions ajaxOpts = new AjaxOptions { UpdateTargetId = "tabledata" }; } <h4>Appointment List</h4> @using (Ajax.BeginForm("AppointmentData", ajaxOpts)) { <table> <thead> <th>Client Name</th> <th>Appointment Date</th> </thead> <tbody id="tabledata"> @Html.Action("AppointmentData", new { id = Model}) </tbody> </table> <p> @Html.DropDownList("id", new SelectList(new[] {"All", "Joe", "Jane", "Bob"}, (Model ?? "All"))) <input type="submit" value="Sumbit" /> </p> }
OK,这样点击按钮时就会在后台发送一个Ajax请求。
实现剖析
AjaxOptions类会被转换成Html元素,这是Ajax帮助类实现的。比如,我们上面的Ajax.BeginForm()会输出下面的HTML。
<form action="/Appointment/AppointmentData" data-ajax="true" data-ajax-mode="replace" data-ajax-update="#tabledata" id="form0" method="post">
jquery.unobtrusive-ajax.js会扫描HTML的DOM对象,通过data-ajax="true"识别ajax form。别的data-ajax开头的属性是我们在AjaxOptions中设置的相应属性。
以上是使用了MVC框架的AJAX支持。你也可以选择不使用这种方式,比如完全使用JQUERY,或者使用别的框架,或者直接使用JS。但是不要在一个View中混合使用以上方式,以免发生冲突而得到意外的结果。
设置AJAX选项
我们可以通过设置AjaxOptions的属性很好地调整我们的AJAX请求的行为。
优雅切换
上面的例子中,我们做到了使用Ajax做请求,但这依赖于客户端启用JS。一旦客户端禁用JS,那一切将变得徒劳无功。
最简单的解决办法是设置AjaxOptions中的Url属性,通过使用Url.Action(action method)方法,同时使用Ajax.BeginForm(AjaxOptions)方法。如果客户端启用JS支持,那么一切仍然是正常的,否则就会Index action会收到Post请求,然后整个页面都会刷新。