jquery.unobtrusive-ajax是微软的一个js文件。和MVC配合使用,可以实现无刷新提交。
主要原理就是通过post方法提交数据后,返回的一般是PartialView或者View,然后把返回的这块东西,替换或者插入到当前网页的某个DOM中去。
比如有如下的一个需求,当输入ID后,按search后自动填满其他的格子。
那么设计的时候,先设计一个PartialView。
如下:
- partial.cshtml
- @model MvcApplication1.Models.PersonModel
- <script src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
- <div id="div1">
- @*此处说明返回后的html是替换div1的*@
- @using (Ajax.BeginForm("Search", "Test", new AjaxOptions { UpdateTargetId = "div1", InsertionModeInsertionMode = InsertionMode.Replace }))
- {
- <b>ID:</b> @Html.TextBoxFor(m =>m.id)<br />
- <b>name:</b> @Html.TextBoxFor(m => m.name)<br />
- <b>age:</b> @Html.TextBoxFor(m => m.age)<br />
- <b>gender:</b> @Html.CheckBoxFor(m => m.gender)<br />
- <p>
- <input type="submit" value="search" />
- </p>
- }
- </div>
Index.cshtml 超简单
- <h2>index</h2>
- @{
- Html.RenderPartial("partial");
- }
TestController.cs
- public ActionResult Search( MvcApplication1.Models.PersonModel model)
- {
- ModelState.Remove("age");
- ModelState.Remove("name");
- ModelState.Remove("gender");//必须的,不然界面上文本框的值不变
- if (model.id == 1)
- {
- model.name = "zhangsan";
- model.age = 21;
- model.gender = true;
- }
- else if (model.id == 2)
- {
- model.name = "lisi";
- model.age = 30;
- model.gender = false;
- }
- else
- {
- int tmp = model.id;
- model = new Models.PersonModel();
- model.id = tmp;
- }
- return PartialView("partial", model);
- }
如上的那些代码
当点击提交,controller中action方法会返回整个PartialView,然后替换原始网页中的那部分。
整个方法效率不是很高,如果整个PartialView页面内容很多,那么返回的东西就会很多。因此,最好的做法是单纯的返回一个json,然后通过json来解析值。因此,重点是写一个通用的js方法,处理json。
此处对上面这个例子,增加一个radio框,使得演示的效果更全面。
代码如下:
partial.cshtml
- @model MvcApplication1.Models.PersonModel
- <div id="div1">
- @using (Html.BeginForm("Search", "Test"))
- {
- <b>ID:</b> @Html.TextBoxFor(m => m.id)<br />
- <b>name:</b> @Html.TextBoxFor(m => m.name)<br />
- <b>age:</b> @Html.TextBoxFor(m => m.age)<br />
- <b>gender:</b> @Html.CheckBoxFor(m => m.gender)<br />
- <b>city:</b> <b>上海</b> @Html.RadioButtonFor(m => m.city, "上海", new { @id = "radio1" }) <b>北京</b> @Html.RadioButtonFor(m => m.city, "北京", new { @id = "radio2" })<br />
- <p>
- <input id="sub" type="button" value="search" />
- </p>
- }
- </div>
- <script type="text/javascript">
- $(function () {
- //搜索
- $("#sub").click(function () {
- var form = $(this).parents("form");
- $.ajax({
- type: 'POST',
- url: $(form).attr("action"),
- data: $(form).serializeArray(),
- success: function (result) {
- processJson(result);
- },
- dataType: "json",
- error: function (XMLHttpRequest, textStatus, errorThrown) { alert(textStatus); }
- });
- });
- })
- //此处处理json返回值。
- function processJson(model) {
- for (var key in model) {
- if ($("#" + key).is(":checkbox")) {
- $("#" + key).attr("checked", model[key]);
- }
- else if ($("input[name='" + key + "']").eq(0).is(":radio")) {//对radio的元素要特殊处理。
- $("input[name='" + key + "']").attr("checked", false);
- $("input[name='" + key + "'][value='" + model[key] + "']").attr("checked", true);
- } else {
- $("#" + key).val(model[key]);
- }
- }
- }
- </script>
TestController.cs
- public ActionResult Search(MvcApplication1.Models.PersonModel model)
- {
- //ModelState.Remove("age");
- //ModelState.Remove("name");
- //ModelState.Remove("gender");
- if (model.id == 1)
- {
- model.name = "zhangsan";
- model.age = 21;
- model.gender = true;
- model.city = "上海";
- }
- else if (model.id == 2)
- {
- model.name = "lisi";
- model.age = 30;
- model.gender = false;
- model.city = "北京";
- }
- else
- {
- int tmp = model.id;
- model = new Models.PersonModel();
- model.id = tmp;
- }
- return Json(model);
- }
以上代码,无需用到jquery.unobtrusive-ajax类库。通过jquery自带的ajax方法,提交到controller的action方法。然后返回值是json,这就大大的缩小的返回内容。通过页面上javascript方法,处理json,并回填到页面。