忽然发现周围的人都是高级编程人员,而我是介于初级和高级之间。顺便吟诗一首,“千山鸟飞绝,万径人踪灭。野旷天低树,江清月近人。”,,我们进入正题。首先来看一下效果图
本篇文章和上篇文章讲的是同一个界面,但是本片讲述的AJAX实现。首先,先看前台代码
- @using MVCRestServiceDemo.Models.Response;
- @using MVCRestServiceDemo.Models;
- @model DataResponse<person_info>
- <!DOCTYPE html>
- <html>
- <head>
- <meta name="viewport" content="width=device-width" />
- <title>档案信息</title>
- <script type="text/javascript" src="~/Scripts/jquery-1.6.2.min.js"></script>
- <script type="text/javascript" src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
- <script type="text/javascript">
- jQuery(document).ready(function () {
- setRowBackColor();
- $("#btnQuery").click(function () { /*查询*/
- queryData();
- });
- });
- function queryData()
- {
- var pageIndex = 1;
- var pageSize = 10;
- var no = $("#txtNo").val();
- var name = $("#txtName").val();
- var sex = $("#ddlSex").val();
- var condition = pageIndex + "_" + pageSize + "_" + no + "|" + name + "|" + sex;
- $.ajax({
- url: "/Home/GetArchiveInfoByConditionAjax/" + condition,
- type: "POST",
- datatype: "Html",
- beforeSend: function () {
- $("#updateProgressDiv").show();
- },
- complete: function () {
- $("#updateProgressDiv").hide();
- },
- success: function (data) {
- $("#archiveInfoPartialDiv").html(data);
- setRowBackColor();
- },
- error: function () {
- alert("查询失败!");
- }
- });
- }
- function checkall() { /*全选*/
- if ($("#chkall").attr("checked")) {
- $(".mytable :checkbox").attr("checked", true);
- }
- else {
- $(".mytable :checkbox").attr("checked", false);
- }
- }
- function setRowBackColor() /*隔行变色*/ {
- var t = document.getElementById("tabArchiveInfo").getElementsByTagName("tr");
- for (var i = 0; i < t.length; i++) {
- t[i].style.backgroundColor = (t[i].sectionRowIndex % 2 == 0) ? "#b7b3b3" : "#fff";
- }
- }
- function setCheck(id) /*点击行选中或取消选中行首复选框*/ {
- $("#chk_" + id).attr("checked", !$("#chk_" + id).attr("checked"));
- }
- function ShowArchiveInfoModify(no) {
- var w = (screen.width - 500) / 2;
- var h = (screen.height - 210) / 2;
- var paramStr = "dialogWidth=500px;dialogHeight=210px;dialogTop=" + h + "px;dialogLeft=" + w + "px;center=yes;middle=yes;help=no;status=no;scroll=no;resizable:no;location:no;";
- window.showModalDialog("/Home/ShowArchiveInfoModify/" + no, null, paramStr);
- queryData();
- }
- </script>
- </head>
- <body>
- <div style="margin: 10px" align="center">
- @using (Ajax.BeginForm("Delete", "Home", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "archiveInfoPartialDiv", InsertionModeInsertionMode = InsertionMode.Replace }))
- {
- <table style="width: 96%; margin-bottom: 3px">
- <tr>
- <td align="right">档案编号: </td>
- <td align="left">
- @Html.TextBox("no", string.Empty,new { id = "txtNo" })
- </td>
- <td align="right">姓名: </td>
- <td align="left">
- @Html.TextBox("name", string.Empty, new { id = "txtName" })
- </td>
- <td align="right">性别: </td>
- <td align="left">
- @Html.DropDownList("sex", (TempData["selectList"] as SelectList), new { id = "ddlSex" })
- </td>
- <td aling="center">
- <input id="btnQuery" type="button" value="查询" style="width: 80px" />
- </td>
- </tr>
- </table>
- Html.RenderPartial("~/Views/PartialView/ArchiveInfoUserControl.cshtml");
- <div style="width: 96%; margin-top: 5px" align="right">
- <button type="button" style="width: 80px;">增加</button>
- <button type="button" style="width: 80px" id="btnDelete">删除</button>
- </div>
- }
- </div>
- <div id="updateProgressDiv" style="display: none;text-align: center">
- <img src="~/Images/throbber.gif" alt="loading" />
- <label>正在加载,请稍后......</label>
- </div>
- </body>
- </html>
我们看这个queryData函数,查询的时候用的AJAX方式,当回调回来以后,将界面输出至archiveInfoPartialDiv这个DIV。这个DIV在哪呢?我们发现上面的代码中没有,那它肯定在用户控件里面了。
- @using MVCRestServiceDemo.Models.Response;
- @using MVCRestServiceDemo.Models;
- @model DataResponse<person_info>
- <div id="archiveInfoPartialDiv">
- <table class="mytable" id="tabArchiveInfo">
- <tr>
- <th>
- <center>
- @Html.CheckBox("chk_all", new { id = "chkall", onclick = "checkall()" })
- </center>
- </th>
- <th>
- <center>档案编号</center>
- </th>
- <th>
- <center>姓名</center>
- </th>
- <th>
- <center>性别</center>
- </th>
- <th>
- <center>身份证号</center>
- </th>
- <th>
- <center>出生日期</center>
- </th>
- <th>
- <center>毕业院校</center>
- </th>
- <th>
- <center>学历</center>
- </th>
- <th>
- <center>专业</center>
- </th>
- <th>
- <center>操作</center>
- </th>
- </tr>
- @foreach (var personInfo in Model.DataList)
- {
- <tr onclick="setCheck('@personInfo.id')">
- <td style="text-align: center;">
- @Html.CheckBox(string.Concat("chk_", personInfo.id), false, new { id = string.Concat("chk_", personInfo.id), onclick = "setCheck('" + personInfo.id + "')" })
- @Html.Hidden(string.Concat("hfd_", personInfo.id), personInfo.id)
- </td>
- <td>
- @personInfo.no
- </td>
- <td>
- @personInfo.name
- </td>
- <td>
- @(personInfo.sex == "1" ? "男" : "女")
- </td>
- <td>
- @personInfo.id_card
- </td>
- <td>
- @personInfo.birth
- </td>
- <td>
- @personInfo.graduate_school
- </td>
- <td>
- @personInfo.education_level
- </td>
- <td>
- @personInfo.professional
- </td>
- <td>
- <button type="button" style="width: 60px; margin-right: 3px" onclick="ShowArchiveInfoModify('@personInfo.id')">
- 修改
- </button>
- <button type="submit" style="width: 60px">删除</button>
- </td>
- </tr>
- }
- </table>
- <div class="divpager">
- 共有 <font color="red" id="ft">@Model.TotalCount</font>条记录 当前是第 <font color="red">@Model.PageIndex</font>
- 页 共<font color="red">@Model.TotalPages</font>页
- @if (Model.HasPreviousPage)
- {
- @Ajax.ActionLink("首页", "GetArchiveInfoByConditionAjax", new { id = string.Join("_", "1", Model.PageSize, ViewBag.Conition) }, new AjaxOptions() { HttpMethod = "Get", InsertionModeInsertionMode = InsertionMode.Replace, UpdateTargetId = "archiveInfoPartialDiv",LoadingElementId="updateProgressDiv", OnSuccess="setRowBackColor();" })<label>
- </label>
- @Ajax.ActionLink("上一页", "GetArchiveInfoByConditionAjax", new { id = string.Join("_", Model.PageIndex - 1, Model.PageSize, ViewBag.Conition) }, new AjaxOptions() { HttpMethod = "Get", InsertionModeInsertionMode = InsertionMode.Replace, UpdateTargetId = "archiveInfoPartialDiv",LoadingElementId="updateProgressDiv", OnSuccess="setRowBackColor();" })<label>
- </label>
- }
- else
- {
- <text>首页 </text>
- <text>上一页 </text>
- }
- @if (Model.HasNextPage)
- {
- @Ajax.ActionLink("下一页", "GetArchiveInfoByConditionAjax", new { id = string.Join("_", Model.PageIndex + 1, Model.PageSize, ViewBag.Conition) }, new AjaxOptions() { HttpMethod = "Get", InsertionModeInsertionMode = InsertionMode.Replace, UpdateTargetId = "archiveInfoPartialDiv",LoadingElementId="updateProgressDiv", OnSuccess="setRowBackColor();" })<label>
- </label>
- @Ajax.ActionLink("末页", "GetArchiveInfoByConditionAjax", new { id = string.Join("_", Model.TotalPages, Model.PageSize, ViewBag.Conition) }, new AjaxOptions() { HttpMethod = "Get", InsertionModeInsertionMode = InsertionMode.Replace, UpdateTargetId = "archiveInfoPartialDiv",LoadingElementId="updateProgressDiv" , OnSuccess="setRowBackColor();"})
- }
- else
- {
- <text>下一页 </text>
- <text>末页 </text>
- }
- </div>
- </div>
果然在这里。在第一段代码中,我们在点击修改按钮的时候弹出一个修改界面,即ShowArchiveInfoModify函数,这个函数接收一个参数,然后调用"/Home/ShowArchiveInfoModify/" + no这个URL,Modal页面修改完数据关闭的时候,调用queryData函数异步刷新界面。我们看到这个代码 @Ajax.ActionLink("首页", "GetArchiveInfoByConditionAjax", new { id = string.Join("_", "1", Model.PageSize, ViewBag.Conition) }, new AjaxOptions() { HttpMethod = "Get", InsertionMode = InsertionMode.Replace, UpdateTargetId = "archiveInfoPartialDiv",LoadingElementId="updateProgressDiv", OnSuccess="setRowBackColor();" })。这就是我们的AJAX方式分页。关于这个Ajax.ActionLink有很多重载,具体的自己看。我这个第一个参数是超链接名字,第二个参数是Action名字,第三个参数是RouteValues,第四个参数AjaxOptions。关于这个AjaxOptions,我们看看
这个Confirm是确认信息,假如你这个链接是删除,那么你可以设置Confirm="确定要删除吗?"。如果你确定,那么就执行删除的Action,否则不执行。看到这个LoadingElementDuration,这个是指加载界面元素时弹出UpdateProgress的事件间隔,比如淘宝上查询了一批商品,那么会出一个显示正在加载的圆圈。LoadingElementID指的是显示正在加载的元素的ID,比如<div id="loadingelmentId">正在加载.......</div>。在这里我们可以看到是
- <div id="updateProgressDiv" style="display: none;text-align: center">
- <img src="~/Images/throbber.gif" alt="loading" />
- <label>正在加载,请稍后......</label>
- </div>
这个层,当分页调用的时候就显示这个层,调用成功该层隐藏,注意,初始化的层是隐藏的display: none。看到这里,我们发现queryData的代码如下
- $.ajax({
- url: "/Home/GetArchiveInfoByConditionAjax/" + condition,
- type: "POST",
- datatype: "Html",
- beforeSend: function () {
- $("#updateProgressDiv").show();
- },
- complete: function () {
- $("#updateProgressDiv").hide();
- },
- success: function (data) {
- $("#archiveInfoPartialDiv").html(data);
- setRowBackColor();
- },
- error: function () {
- alert("查询失败!");
- }
- });
在这里其实用jquery也可以轻松实现loading效果,主要的就是beforesend和complete。OnBegin,就是调用AJAX之前,OnComplete就是调用结束后,OnFailure就是调用失败,OnSuccess就是调用成功,在这里就是当异步调用成功以后,给partial页面设置隔行变色,调用setRowBackColor函数。再下来有一个HttpMethod,这个就是请求的方式POST还是GET。InsertionMode则是插入的方式,比如AJAX调用结束以后,返回的是一个页面cshtml,这个时候你要指定这个InsertionMode
我们看到有三个枚举值,一个是InsertAfter,意思是在之后插入,InsertBefore是在之前插入,Replace则是替换,由于我们在这里是分页,所以肯定是Replace,因为我们每次返回的都是一页数据。有一种场景,可能用到InsertAfter,比如,我增加一个东西,我每次增加完以后我都要看见这个东西增加成功了,这个时候,后台只需要把刚插入的这条返回,然后InsertAfter即可。InsertBefore场景比如我点击删除,然后后台返回一个由于什么原因不能删除的信息,这个时候可以显示在form的最顶,就用InsertBefore,总之InsertAfter和Before强调的增量,而Replace强调的是覆盖。最后的一个参数UpdateTargetId,意思是要更改的元素ID,一般是DIV。在这里我们每次分页要更新的是archiveInfoPartialDiv这个DIV元素。OK,前台基本没什么了。我们看看后台
- #region ajax page
- public ViewResult GetArchiveInfoAjax()
- {
- string uri = string.Format(baseAddress + "PersonInfo/GetAll/{0}/{1}", 1, 10);
- ViewBag.Conition = string.Join("|", string.Empty, string.Empty, string.Empty);
- DataResponse<person_info> personInfoList = dataService.GetData<DataResponse<person_info>>(uri);
- this.GetSexList();
- return View("~/Views/Home/ArchiveInfoAjax.cshtml", personInfoList);
- }
- public PartialViewResult GetArchiveInfoByConditionAjax(string id)
- {
- string[] pageValues = id.Split("_".ToCharArray());
- int pageIndex = int.Parse(pageValues.ElementAt(0));
- int pageSize = int.Parse(pageValues.ElementAt(1));
- string[] searchValues = pageValues[2].Split("|".ToCharArray());
- string no = searchValues.ElementAt(0) ?? string.Empty;
- string name = searchValues.ElementAt(1) ?? string.Empty;
- string sex = searchValues.ElementAt(2) ?? string.Empty;
- PersonRequest request = new PersonRequest()
- {
- No = no.Trim(),
- Name = name.Trim(),
- Sex = sex.Trim(),
- PageSize = pageSize,
- PageIndex = pageIndex
- };
- ViewBag.No = request.No;
- ViewBag.Name = request.Name;
- ViewBag.Conition = string.Join("|", no.Trim(), name.Trim(), sex.Trim());
- string uri = baseAddress + "PersonInfo/GetByCondition";
- DataResponse<person_info> personInfoList = dataService.GetData<DataResponse<person_info>, PersonRequest>(uri, request);
- return PartialView("~/Views/PartialView/ArchiveInfoUserControl.cshtml", personInfoList);
- }
- public ViewResult ShowArchiveInfoModify(string id)
- {
- string uri = string.Format(string.Concat(baseAddress, "PersonInfo/GetPersonInfo/{0}"),id);
- person_info personInfo = dataService.GetData<person_info>(uri);
- this.GetSexList(string.Empty);
- this.GetEducationList(string.Empty);
- this.GetProfessionalList(string.Empty);
- return View("~/Views/Home/ArchiveInfoModify.cshtml",personInfo);
- }
- public JavaScriptResult ModifyPersonInfo(person_info personInfo)
- {
- if (string.IsNullOrEmpty(personInfo.education_level))
- {
- return JavaScript("alert('学历不能为空!');");
- }
- string uri = string.Concat(baseAddress, "PersonInfo/ModifyPersonInfo");
- int suc=dataService.DealData<int, person_info>(uri,personInfo);
- return JavaScript("alert('修改成功!');window.close();");
- }
- private void GetEducationList(string selectedValue="")
- {
- string uri = baseAddress + "PersonInfo/GetEducation";
- List<codes> codeList = dataService.GetData<List<codes>>(uri);
- codeList.Insert(0, new codes() { data = string.Empty, display_content = "---请选择---" });
- SelectList selectList = new SelectList(codeList, "data", "display_content", selectedValue);
- ViewBag.EducationList = selectList;
- }
- private void GetProfessionalList(string selectedValue = "")
- {
- string uri = baseAddress + "PersonInfo/GetProfessional";
- List<codes> codeList = dataService.GetData<List<codes>>(uri);
- codeList.Insert(0, new codes() { data = string.Empty, display_content = "---请选择---" });
- SelectList selectList = new SelectList(codeList, "data", "display_content", selectedValue);
- ViewBag.ProfessionalList = selectList;
- }
- #endregion
一些获取下拉列表数据,查询,获取Modal页面,修改信息。GetArchiveInfoAjax这个是初始化界面,GetArchiveInfoByConditionAjax这个是分页,和非AJAX界面不同的是,它返回的是我们的partial页PartialView("~/Views/PartialView/ArchiveInfoUserControl.cshtml", personInfoList)用这个页面去替换上一页数据。ShowArchiveInfoModify界面则是返回showModal界面,并且给它绑定一个要修改的对象。ModifyPersonInfo就是修改信息了,在这里我们写了一个简单的check,然后return JavaScript("alert('学历不能为空!');"),注意在这里,如果return JavaScript,则要在页面引用jquery.unobtrusive-ajax.min.js,否则不能正确执行javascript。好了,我们再看看我们的WCF Service
- public person_info GetPersonInfo(string id)
- {
- person_info personInfo = misInfoEntities.person_info.Find(id);
- return personInfo;
- }
- public int ModifyPersonInfo(person_info personInfo)
- {
- person_info person_Info = misInfoEntities.person_info.Find(personInfo.id);
- person_Info.name = personInfo.name;
- person_Info.id_card = personInfo.id_card;
- person_Info.sex = personInfo.sex;
- person_Info.education_level = personInfo.education_level;
- person_Info.professional = personInfo.professional;
- person_Info.graduate_school = personInfo.graduate_school;
- person_Info.graduate_year = personInfo.graduate_year;
- person_Info.contact_tel = personInfo.contact_tel;
- misInfoEntities.Entry<person_info>(person_Info).State = EntityState.Modified;
- return misInfoEntities.SaveChanges();
- }
没什么可说的,很简单,今天就到这里,我还没写完呢,就被评为推荐,在此谢过,收拾上班。