2018年01月10日 21:20
原创作品,转载时请务必以超链接形式标明文章原始出处,否则将追究法律责任。

忽然发现周围的人都是高级编程人员,而我是介于初级和高级之间。顺便吟诗一首,“千山鸟飞绝,万径人踪灭。野旷天低树,江清月近人。”,,我们进入正题。首先来看一下效果图

213115311.jpg

214027521.jpg

073715710.jpg


本篇文章和上篇文章讲的是同一个界面,但是本片讲述的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>页&nbsp;&nbsp;&nbsp;&nbsp;  
        @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>&nbsp;  
            </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>&nbsp;  
            </label>   
        }  
        else  
        {  
            <text>首页&nbsp;</text> 
            <text>上一页&nbsp;</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>&nbsp;  
            </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>下一页&nbsp;</text>   
            <text>末页&nbsp;</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,我们看看

215532264.jpg

这个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

6365121696159725175235140.jpg

我们看到有三个枚举值,一个是InsertAfter,意思是在之后插入,InsertBefore是在之前插入,Replace则是替换,由于我们在这里是分页,所以肯定是Replace,因为我们每次返回的都是一页数据。有一种场景,可能用到InsertAfter,比如,我增加一个东西,我每次增加完以后我都要看见这个东西增加成功了,这个时候,后台只需要把刚插入的这条返回,然后InsertAfter即可。InsertBefore场景比如我点击删除,然后后台返回一个由于什么原因不能删除的信息,这个时候可以显示在form的最顶,就用InsertBefore,总之InsertAfterBefore强调的增量,而Replace强调的是覆盖。最后的一个参数UpdateTargetId,意思是要更改的元素ID,一般是DIV。在这里我们每次分页要更新的是archiveInfoPartialDiv这个DIV元素。OK,前台基本没什么了。我们看看后台

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;  
        }

一些获取下拉列表数据,查询,获取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();  
        }

没什么可说的,很简单,今天就到这里,我还没写完呢,就被评为推荐,在此谢过,收拾上班。

发表评论
匿名  
用户评论
暂无评论